Design patterns 工厂模式-CreateInstance是否为静态?

Design patterns 工厂模式-CreateInstance是否为静态?,design-patterns,factory,factory-pattern,factory-method,static-factory,Design Patterns,Factory,Factory Pattern,Factory Method,Static Factory,这是关于工厂模式的。我有点困惑 我看到了createInstance()方法是静态的实现和一些非静态的实现 有人说这取决于“风格”或“品味”,也有人说不是。 根据四人帮的说法,维基百科说它应该是非静态的,也说它应该是非静态的 我的问题是:它是否依赖于风格和品味,或者如果以静态方式实现,它是否违反了工厂模式?什么是正确的?如果它是一个抽象工厂,那么实例级别是正常的。实例级功能往往比静态方法更容易模拟和单元测试,静态方法并不违反模式,但它与许多其他面向对象的实践(例如控制反转+依赖项注入)相反,因此

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

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

有人说这取决于“风格”或“品味”,也有人说不是。 根据四人帮的说法,维基百科说它应该是非静态的,也说它应该是非静态的


我的问题是:它是否依赖于风格和品味,或者如果以静态方式实现,它是否违反了工厂模式?什么是正确的?

如果它是一个
抽象工厂
,那么实例级别是正常的。实例级功能往往比静态方法更容易模拟和单元测试,静态方法并不违反模式,但它与许多其他面向对象的实践(例如控制反转+依赖项注入)相反,因此使用实例更好

编辑:

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

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


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

我很犹豫是否将“实例与静态”归类为品味问题。这意味着它的美感就像是一种最受欢迎的颜色,或者更贴切地说,是驼色还是帕斯卡色

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

如果你有一个静态方法——比如说你的例子中的工厂方法——并且你以后希望它在某些情况下表现不同,那么你就有点不知所措了。您必须创建第二个方法,复制并粘贴功能减去您想要更改的内容,然后让客户机找出它。或者,更糟糕的是,您公开了一个全局变量,并让客户端在使用您的方法之前和之后进行设置,全局变量告诉方法如何操作

如果您走的是前面的实例路线,这将很容易。您只需继承和重写初始工厂方法,并在需要新功能的地方提供派生类。您不会给客户机代码增加额外的负担,并且几乎不会对现有类进行任何修改(开放/封闭原则)


我的建议是帮你和/或其他维护人员的忙,使用实例实现。这不是“四人帮”或其他任何人想要或喜欢什么的问题,而是你在面对代码腐烂时的理智问题。

你不能使用静态注入,比如
静态无效设置工厂(工厂事实)
?好的,谢谢。我不需要改变任何事情。你的论点符合我对oop的看法。感谢您的确认。@corsiklausehoho-这样做意味着您必须记住每次需要使用工厂时都要使用setFactory()。与实例类不同,您需要使用构造函数,从而减轻了必须记住所需方法的负担。@Yorro否,您只需要在系统启动时或由于用户请求的配置更改而按需设置工厂一次。您仍然可以根据配置设置动态注入它。如果我每次都调用setFactory(),我会想象我会使用构建器而不是工厂,通过静态方法运行它们会涉及一些技巧,比如内部的threadlocal。。。如果那样的话,我宁愿有一个建筑工人工厂。。。