代码之家  ›  专栏  ›  技术社区  ›  Tyler Carter

你是如何创建工厂的?

  •  3
  • Tyler Carter  · 技术社区  · 16 年前

    所以,说到工厂,我想知道它们是如何建立的。

    站在这里,我可以看到三种类型的工厂:

    一体式

    基本上包含应用程序中使用的所有类的工厂。感觉只是为了有个工厂才有个工厂,并没有真正的结构感。

    例子 (如果ClassA、Class B和ClassC除了在同一个应用程序中之外没有任何共同点) :

    class Factory
    {
     public static function buildClassA()
     public static function buildClassB()
     public static function buildClassC()
    }
    

    提供的代码示例是用php编写的。然而,这个问题是语言不可知论的。

    内建工厂

    下一个是将静态函数与常规函数混合,以便生成特殊的创建模式(请参见 this question )

    例子:

    class ClassA
    {
     public static function buildClass()
     public function __construct()
    }
    

    旁边的工厂

    我能想到的最后一个方法是为单个类或单个类集创建一个工厂。这似乎只是以一种统一的方式使用。

    示例(其中A、B和C类是相关的,1、2和3类是相关的):

    class FactoryAlpha
    {
     public static function buildClassA()
     public static function buildClassB()
     public static function buildClassC()
    }
    
    class FactoryNumeric
    {
     public static function buildClass1()
     public static function buildClass2()
     public static function buildClass3()
    }
    

    我的问题是:这些都是坏主意,有没有坏主意?有没有其他方法来创建工厂?这些真的是好主意吗?创建工厂的最佳方法是什么?

    3 回复  |  直到 16 年前
        1
  •  5
  •   Thilo    16 年前

    工厂的重点似乎是拥有使用它的代码,而不需要知道将构造哪个具体类(这应该通过配置工厂来处理)。这似乎排除了“一体式”和“边上工厂”的可能性。

    我喜欢Java库经常使用的方法:您有一个创建工厂的静态方法。工厂有一个getInstance方法来创建实例。这为您提供了两点配置(通过系统属性):默认的factoryimpl有许多设置,比如它应该生成的类,如果这些配置选项不够,您还可以将factoryimpl全部替换掉。

    至于“多合一”和“边上工厂”,我认为工厂不应该生产不相关的类。同样,它是Java术语,每一个工厂都会产生特定接口的实例。

    “all-in-one”听起来像是应该用依赖注入代替的东西(在这里,您有一个容器,可以生成各种实例并将它们注入到应用程序中)。

        2
  •  2
  •   Bill K    16 年前

    如果你真的对“首选技术”感兴趣,我会用依赖注入来替换它们。

    如果这看起来很重,请记住您可能没有看到工厂的所有用途,所以不要在工厂中“新建”硬编码类。相反,有一个“setter”可以指定需要注入什么类。

    当您进行单元测试并需要开始注入模拟类时,这将很有用。

    但是,当您使它更加通用、抽象和可重用时,您将回到di。(别说我没警告你)

        3
  •  0
  •   Dave Sims    16 年前

    实际上只有两种标准的工厂,至少根据 GOF 以及 slew 属于 patterns 那些书 followed :基本 Factory ,以及 Abstract Factory

    工厂通常返回调用方通过接口引用的具体实例,如下所示:

    // createWidget() here instantiates a BigWidget or SmallWidget or whatever the context calls for
    IWidget widget = WidgetFactory.createWidget(someContextValue);
    

    以这种方式使用带有接口的工厂可以防止调用方耦合到返回对象的特定类型中。追随尊者 Single Responsibility Principle ,工厂应该做一件事,即返回调用的接口的具体实例,而不是更多。基本工厂应该只负责创建一种类型的对象。

    另一方面,一个抽象的工厂可以被认为是一个工厂工厂,可能更接近于你所认为的“一体式”工厂。抽象工厂通常在启动时配置为返回一组相关工厂,例如根据给定上下文可能创建特定gui系列的工厂。这是一个例子 Dependency Inversion 这在很大程度上被ioc容器所取代,比如 Spring

    推荐文章