工厂模式 - CreateInstance静态与否?

时间:2011-10-26 20:13:41

标签: design-patterns factory factory-pattern factory-method static-factory

这是关于工厂模式的。我有点困惑。

我看到createInstance()方法是静态的实现和一些非静态的实现。

有人说这取决于“风格”或“品味”,有些人说它没有。 根据四人组的说法,维基百科说它应该是非静态的,http://www.dofactory.com/Patterns/PatternFactory.aspx也说它应该是非静态的。

我的问题是:它取决于风格和味道还是违反工厂模式,如果它是以静态方式实现的?什么是对的?

3 个答案:

答案 0 :(得分:43)

我非常犹豫将“实例与静态”分类为品味问题。这种暗示它的美学就像一种喜欢的颜色,或更合适的,camelCase与PascalCase。

实例与静态更是一个权衡问题。使用任何类型的实例成员,您都可以获得多态性的所有好处,因为您可以在拥有实例和实例成员时实现接口并从其他类继承。使用静力学,您无法获得这些好处。通常,静态与实例是前期简单性与下游简单性之间的权衡。静态很容易,因为它们是全局可访问的,您不必考虑诸如“何时应该实例化以及由谁实现?”之类的事情。您不必使用访问器/ mutator或构造函数传递它们,并且您的API 看起来更干净。这使前期推理更容易。但是,它使维护和未来的实施更加困难。

如果你有一个静态的方法 - 在你的情况下说一个工厂方法 - 而你后来希望它在某些情况下表现不同,那么你就是一种软管。您必须制作第二种方法并复制并粘贴功能减去您想要更改的内容,然后让客户端弄明白。或者更糟糕的是,您公开了一个全局变量,让客户在使用您的方法之前和之后设置它,全局告诉方法如何表现。

如果你已经预先走了实例路线,这很容易。您只需继承并覆盖初始工厂方法,并在需要新功能的地方提供派生类。您不会给客户端代码带来额外负担,并且您几乎不会对现有类进行任何修改(开放/封闭原则)。

我的建议是为您和/或其他维护人员提供帮助并使用实例实现。这不是“四人帮”或其他任何人想要或更喜欢的问题 - 面对代码腐烂,这是你自己的理智问题。

答案 1 :(得分:18)

静态方法不违反模式,但它违背了许多其他面向对象的实践(控制反转+依赖注入作为一个例子),所以使用实例更好。

修改

我刚拿到这个答案的徽章,但是当我读到它时,我简直不敢相信自己的眼睛。我们严格地谈论GoF Factory方法模式是错误的,值得一些纠正。

您可以使用静态CreateInstance方法创建类型的实例 - 没有任何错误 - 人们通常将其称为工厂方法,但这不是所谓的工厂方法模式 。一旦开始将逻辑放入此方法以根据某些条件创建不同类型的实例,您可能实际上需要GoF描述的工厂方法模式。

GoF Factory方法模式的要点是用继承和多态替换CreateInstance内的条件逻辑,因此它不能是静态的。工厂方法是一种实例方法 - 而且它是虚拟的。您的基类型通常是抽象CreateInstance,条件逻辑由继承树替换,其中每个子类型覆盖CreateInstance并仅为该子类型创建特定产品。

答案 2 :(得分:7)

如果它是abstract factory那么实例级别是正常的。实例级功能往往比static

更容易进行模拟和单元测试