代码之家  ›  专栏  ›  技术社区  ›  Castrohenge

工厂模式:枚举还是类型?

  •  6
  • Castrohenge  · 技术社区  · 16 年前

    例如

    public class SimpleFactory
    {
     public static ITest Create(Type type)
     {
      if (type == typeof(ConcreteTest1))
       return new ConcreteTest1();
      if (type == typeof(ConcreteTest2))
       return new ConcreteTest2();
    
      throw new Exception("Invalid type");
     }
    }
    
    6 回复  |  直到 16 年前
        1
  •  16
  •   Reed Copsey    16 年前

    使用枚举更具限制性,这意味着用户不太可能尝试使用不支持类型的工厂。

    我发现,在定义API时尽一切可能阻止会引发异常的使用模式是很好的。在这种情况下,允许“Type”打开了数百万种调用函数的方法,这将导致:

    throw new Exception("Invalid type");
    

    使用枚举可以消除这种情况。枚举抛出的唯一方法是如果用户犯了明显的错误。

        2
  •  5
  •   Jamie Ide    16 年前

    工厂只有在对对象执行配置或初始化以使其处于有效状态时才有用。如果一个工厂所做的只是新建并返回对象,我就不会为它操心。

    public abstract class Vehicle {}
    public class Car : Vehicle {}
    public class Truck : Vehicle {}
    
    public class VehicleFactory
    {
        public Vehicle CreateVehicle<T>() where T : Vehicle
        {
            // Get type of T and delegate creation to private methods
        }
    }
    
        3
  •  2
  •   dfa    16 年前

    如果你想要一个傻瓜工厂,你必须为每种混凝土类型创建一个混凝土工厂。这个类不遵循开闭原则:每次你得到一个新的具体类型,你都必须重新编辑这个类。

        4
  •  2
  •   Joseph    16 年前

    我更喜欢使用泛型约束,因为拥有一个仅用于指定所需对象类型的枚举对我来说似乎是多余的,并且使用您描述的类型违反了打开/关闭原则。我所能做的与你所能做的不同。

    我将给出一个使用泛型的c#示例。

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

    然后,您将使用ConcreteTest1和ConcreteTest2实现IConcreteTest,您可以像这样使用工厂:

    ConcreteTest1 test1 = SimpleFactory.Create<ConcreteTest1>();
    
        5
  •  1
  •   Robert    16 年前

    如果要按类型创建,可以使用 Activator.CreateInstance(Type t) . 将其包装在模板方法中,以将其限制在您的接口中,例如 Create<T> where T:ITest

        6
  •  1
  •   jeremyalan    16 年前

    我认为我最大的担忧是,工厂的目的是允许客户机代码创建对象的派生实例,而不知道所创建类型的详细信息(更具体地说,是关于如何创建实例的详细信息,但是如果操作正确,调用方不需要知道基类提供的任何更详细的信息)。