【问题标题】:Factory Pattern - CreateInstance static or not?工厂模式 - CreateInstance 是否静态?
【发布时间】:2011-12-16 00:54:20
【问题描述】:

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

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

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

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

【问题讨论】:

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


    【解决方案1】:

    我很犹豫将“实例与静态”归类为品味问题。这意味着它的美感就像是最喜欢的颜色,或者更恰当地说,是驼峰式与帕斯卡式。

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

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

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

    我的建议是帮助未来的您和/或其他维护人员并使用实例实现。这与四人帮或其他任何人想要或喜欢什么无关,而是在面对代码腐烂时您自己的理智。

    【讨论】:

      【解决方案2】:

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

      编辑:

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

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

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

      【讨论】:

      • 你不能使用静态注入,比如static void setFactory(Factory fact)吗?
      • 好的,谢谢。我不需要改变任何东西。你的论点符合我对oop的想法。感谢您确认这一点。
      • @corsiKlauseHoHoHo - 这样做意味着您必须记住每次需要使用工厂时都使用 setFactory()。与实例类不同,您需要使用构造函数,从而减轻您必须记住所需方法的负担。
      • @Yorro 不,您只需在系统启动时或由于用户请求的配置更改而按需设置一次工厂。您仍然可以根据配置设置动态注入它。如果我每次都调用 setFactory() ,我会想象我会使用构建器而不是工厂,并且通过静态方法运行它们会涉及到内部的诸如 threadlocal 之类的诡计......我宁愿有一个工厂在那种情况下的建设者......
      【解决方案3】:

      如果它是abstract factory,那么实例级别是正常的。而且实例级别的功能往往比static 级别更容易模拟和单元测试

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-08-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多