我正在寻找一个如何实现工厂类的简单示例,但不使用Switch或If-Then语句。我可以找到的所有示例都使用一个。例如,如何修改此简单示例(如下),以使实际工厂不依赖于Switch?在我看来,该示例违反了打开/关闭原则。我希望能够添加具体的类(“经理”,“文员”,“程序员”等),而无需修改工厂类。

谢谢!

class Program
{
    abstract class Position
    {
        public abstract string Title { get; }
    }

    class Manager : Position
    {
        public override string Title
        {
            get  { return "Manager"; }
        }
    }

    class Clerk : Position
    {
        public override string Title
        {
            get { return "Clerk"; }
        }
    }

    class Programmer : Position
    {
        public override string Title
        {
            get { return "Programmer"; }
        }
    }

    static class Factory
    {
        public static Position Get(int id)
        {
            switch (id)
            {
                case 0: return new Manager();
                case 1: return new Clerk();
                case 2: return new Programmer();
                default: return new Programmer();
            }
        }
    }

    static void Main(string[] args)
    {
        for (int i = 0; i <= 2; i++)
        {
            var position = Factory.Get(i);
            Console.WriteLine("Where id = {0}, position = {1} ", i, position.Title);
        }
        Console.ReadLine();
    }
}

更新:

哇!谢谢大家!我学到了很多。收集了所有反馈后,我混合了一些答案并提出了答案。我愿意就更好的方法进行进一步的对话。
class Program
{

    public interface IPosition
    {
        string Title { get; }
    }

    class Manager : IPosition
    {
        public string Title
        {
            get { return "Manager"; }
        }
    }

    class Clerk : IPosition
    {
        public string Title
        {
            get { return "Clerk"; }
        }
    }

    class Programmer : IPosition
    {
        public string Title
        {
            get { return "Programmer"; }
        }
    }

static class PositionFactory
{
    public static T Create<T>() where T : IPosition, new()
    {
        return new T();
    }
}


static void Main(string[] args)
    {

        IPosition position0 = PositionFactory.Create<Manager>();
        Console.WriteLine("0: " + position0.Title);

        IPosition position1 = PositionFactory.Create<Clerk>();
        Console.WriteLine("1: " + position1.Title);

        IPosition position2 = PositionFactory.Create<Programmer>();
        Console.WriteLine("1: " + position2.Title);

        Console.ReadLine();
    }
}

另一个编辑:

也可以使用未知类型创建Interface的实例:
static class PositionFactory
{
   public static IPosition Create(string positionName)
    {
        Type type = Type.GetType(positionName);
        return (IPosition)Activator.CreateInstance(type);
    }
}

然后可以这样称呼它:
IPosition position = PositionFactory.Create("Manager");
Console.WriteLine(position.Title);

最佳答案

怎么样(不需要字典,请注意,如果尝试Create<Position>(),将会出现语法错误):

编辑-更新为使用显式实现的IPosition接口(interface)。只有IPosition实例可以访问成员函数(例如<implementation of Manager>.Title将不会编译)。

编辑#2 Factory.Create应该在正确使用接口(interface)时返回IPosition而不是T。

using System;
using System.Collections.Generic;

class Program
{
    interface IPosition
    {
        string Title { get; }
        bool RequestVacation();
    }

    class Manager : IPosition
    {
         string IPosition.Title
        {
            get { return "Manager"; }
        }

        bool IPosition.RequestVacation()
        {
            return true;
        }
    }

    class Clerk : IPosition
    {
        int m_VacationDaysRemaining = 1;

        string IPosition.Title
        {
            get { return "Clerk"; }
        }

        bool IPosition.RequestVacation()
        {
            if (m_VacationDaysRemaining <= 0)
            {
                return false;
            }
            else
            {
                m_VacationDaysRemaining--;
                return true;
            }
        }
    }

    class Programmer : IPosition
    {
        string IPosition.Title
        {
            get { return "Programmer"; }
        }

        bool IPosition.RequestVacation()
        {
            return false;
        }
    }

    static class Factory
    {
        public static IPosition Create<T>() where T : IPosition, new ()
        {
            return new T();
        }
    }

    static void Main(string[] args)
    {
        List<IPosition> positions = new List<IPosition>(3);
        positions.Add(Factory.Create<Manager>());
        positions.Add(Factory.Create<Clerk>());
        positions.Add(Factory.Create<Programmer>());

        foreach (IPosition p in positions) { Console.WriteLine(p.Title);  }
        Console.WriteLine();

        Random rnd = new Random(0);
        for (int i = 0; i < 10; i++)
        {
            int index = rnd.Next(3);
            Console.WriteLine("Title: {0}, Request Granted: {1}", positions[index].Title, positions[index].RequestVacation());
        }

        Console.ReadLine();
    }
}

关于c# - 没有开关或If/Then的工厂模式,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33878216/

10-10 16:48