【问题标题】:How do you create your Factories?你如何创建你的工厂?
【发布时间】:2010-02-02 01:05:58
【问题描述】:

所以,谈到工厂这个主题,我想知道它们是如何设置的。

从我站的地方,我可以看到三种类型的工厂:

一体机

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

示例(其中ClassA、Class B和ClassC除了在同一个App中没有任何共同点)

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()
}

工厂现场

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

示例(其中 ClassA、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()
}

我的问题是:所有这些都是坏主意吗?它们中的任何一个都是坏主意吗?还有其他创建工厂的方法吗?这些真的是好主意吗?什么是创建工厂的好/最佳方式。

【问题讨论】:

  • 关于内置工厂,如果你打算使用静态函数作为工厂,构造函数应该是私有的。

标签: language-agnostic oop factory


【解决方案1】:

工厂的重点似乎是使用它的代码不需要知道将构造哪个具体类(这应该通过配置工厂来处理)。这似乎排除了“All-in One”和“Factory-on-the-Side”。

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

至于“All-in One”与“Factory-on-the-Side”,我认为工厂不应该产生不相关的类。同样,按照 Java 术语,每个工厂都会产生某个接口的实例。

“All-in-One”听起来应该被 Dependency Injection 取代(您有一个容器,可以生成各种实例并将它们注入应用程序)。

【讨论】:

    【解决方案2】:

    如果您真的对“首选技术”感兴趣,我会将它们全部替换为依赖注入。

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

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

    但是当你使这个更通用、抽象和可重用时,你最终会回到 DI。 (只是不要说我没有警告你)

    【讨论】:

      【解决方案3】:

      实际上只有两种标准类型的工厂,至少根据GOFpatterns 书籍中的slew followed:基本的FactoryAbstract 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 的一个示例,它在很大程度上已被使用Spring 等IOC 容器所取代。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-03-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-29
        • 2014-08-28
        相关资源
        最近更新 更多