dkn*_*ack 32 design-patterns factory factory-method factory-pattern static-factory
这是关于工厂模式.我有点困惑.
我看到了createInstance()
方法是静态的实现和一些非静态的实现.
有人说这取决于"风格"或"味道",有些人说它没有.维基百科说它应该是非静态的,并且http://www.dofactory.com/Patterns/PatternFactory.aspx也表示它应该是非静态的,根据Gang of Four的说法.
我的问题是:它是否依赖于风格和品味,或者它是否违反了工厂模式,如果它是以静态方式实现的?什么是对的?
Eri*_*ich 43
我非常犹豫将"实例与静态"分类为品味问题.这种暗示它的美学就像一种喜欢的颜色,或更合适的,camelCase与PascalCase.
实例与静态更是一个权衡问题.对于任何类型的实例成员,您都可以获得多态性的所有好处,因为您可以在拥有实例和实例成员时实现接口并从其他类继承.使用静力学,您无法获得这些好处.通常,静态与实例是前期简单性与下游简单性之间的权衡.静态很容易,因为它们是全局可访问的,您不必考虑诸如"何时应该实例化以及由谁实现?"之类的事情.您不必使用访问器/ mutator或构造函数传递它们,并且您的API 看起来更干净.这使前期推理更容易.但是,它使维护和未来的实施更加困难.
如果你有一个静态的方法 - 比如你的情况下说一个工厂方法 - 并且你后来希望它在某些情况下表现得不同,那么你就会受到冲击.您必须制作第二种方法并复制并粘贴功能减去您想要更改的内容,然后让客户端弄明白.或者更糟糕的是,您公开了一个全局变量,让客户端在使用您的方法之前和之后设置它,全局告诉方法如何表现.
如果你已经预先走了实例路线,这很容易.您只需继承并覆盖初始工厂方法,并在需要新功能的地方提供派生类.您不会给客户端代码带来额外负担,并且您几乎不对现有类进行任何修改(开放/封闭原则).
我的建议是为将来和/或其他维护者做一个忙,并使用实例实现.这不是四人帮或其他任何人想要或更喜欢的问题 - 面对代码腐烂,这是你自己的理智问题.
Lad*_*nka 19
静态方法不违反模式,但它违背了许多其他面向对象的实践(控制反转+依赖注入作为一个例子),因此使用实例更好.
编辑:
我得到了一些这个答案的徽章,但是当我读到它时,我简直不敢相信自己的眼睛.当我们严格地谈论GoF Factory方法模式时它是错误的,它值得一些纠正.
您可以使用静态CreateInstance
方法来创建类型的实例 - 没有任何错误 - 人们经常将其称为工厂方法,但这不是所谓的工厂方法模式.一旦开始将逻辑放入此方法以根据某些条件创建不同类型的实例,您可能实际上需要GoF描述的工厂方法模式.
GoF Factory方法模式的要点是CreateInstance
用继承和多态替换条件逻辑,因此它不能是静态的.工厂方法是一种实例方法 - 而且它是虚拟的.您的基类型通常是抽象的CreateInstance
,条件逻辑由继承树替换,其中每个子类型都会覆盖CreateInstance
并为该子类型创建特定的产品.