【问题标题】:Where should creation conditions migrate in Factory pattern?工厂模式中的创建条件应该迁移到哪里?
【发布时间】:2013-02-08 23:39:00
【问题描述】:

在这张图片上,您可以看到源类中的一些常量,它们帮助工厂生成正确的对象。有人告诉我这是一种反模式,我应该将这些常量移到另一个类。我应该将它们移到工厂类吗?

这是工厂类的代码:

class Factory
{
        public function make($format)
        {
                switch ($format)
                {
                        case Source::Assocs:
                                return new SourceFormatsAssocs();
                        case Source::XML:
                                return new SourceFormatsXML();
                        //Some more formats
                }
        }
}

【问题讨论】:

    标签: design-patterns factory


    【解决方案1】:

    这确实可以防止在不修改基类的情况下添加新的子类(添加新的常量)。我确实会把它搬到工厂。工厂必须知道它可以创建的所有类型的子类。基类不需要知道它的子类。

    此外,这些常量仅由工厂(以及工厂的调用者)使用。基类根本不使用它们。

    【讨论】:

    • 你是对的——但其他类也在使用这些类型。您如何看待在名为 \Formats\Types 的类中创建这些常量?
    • 这也是可以接受的。在我看来,这些常量的主要用途是将它们传递给工厂以选择合适的子类,因此将它们放入工厂对我来说是有意义的。
    • 看我想把所有这些文件放在我的名为 Sol 的库中,使用像 \Sol\Data\Source\Source 和 \Sol\Data\Source\Formats\Assocs(或 Xml,对象)和 \Sol\Data\Source\Formats\Factory。现在我正在考虑客户端编码器,如果他想添加另一种格式,他无法访问 Sol 所以他必须扩展工厂,以提供包含该格式类的文件的路径,并且他必须在他自己的库中扩展 \Sol\Data\Source\Formats\Types ?这合乎逻辑吗?
    • 现在是时候选择一种真正的编程语言了。最佳解决方案取决于您使用的语言。但是你应该使用组合而不是继承来实现你的可扩展工厂。
    • 向工厂添加registerSubclassFactory() 方法,允许客户端代码插入新工厂,从而允许使用新键创建新的子类实例。让基础工厂委托给它的 SubclassFactories。
    【解决方案2】:

    一个更好的主意是考虑一个建造者。为什么?因为您可以拥有一个知道 Formats 类型的抽象类,然后是构造各种子类型的具体 Builders。请注意,当构建涉及通过多个步骤使某些事情变得复杂时,应该完成构建器,但是构建器模式有多种变体,例如 Bloch 中的静态构建器和流利的构建器,您可以使用该模式将调用链接到使代码更具可读性,并内联生成产品。

    另一种可能性是Factory Method。如果您对自己的班级是否值得 Builder 感到不安,这可能是一个很好的匹配。

    【讨论】:

      猜你喜欢
      • 2012-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多