【问题标题】:Confused about this factory, as it doesn't look like an Abstract Factory nor Factory Method对这个工厂感到困惑,因为它看起来不像抽象工厂或工厂方法
【发布时间】:2010-05-25 11:56:29
【问题描述】:

我正在研究 Guice,最近一直在阅读它的文档。

阅读motivation 部分我不明白工厂部分,为什么他们这样命名。对我来说,工厂只是他们希望在调用 getInstance() 后返回的实现类的包装器。

public class CreditCardProcessorFactory {

  private static CreditCardProcessor instance;

  public static void setInstance(CreditCardProcessor creditCardProcessor) {
    instance = creditCardProcessor;
  }

  public static CreditCardProcessor getInstance() {
    if (instance == null) {
      throw new IllegalStateException("CreditCardProcessorFactory not initialized. "
          + "Did you forget to call CreditCardProcessor.setInstance() ?");
    }

    return instance;
  }
}

如果它既不是抽象工厂也不是工厂方法(至少正如 GoF 最初定义的那样),为什么还要称它为工厂?还是我错过了什么?

谢谢。

编辑:如果有人想出更好的标题,我会很高兴更改它。

【问题讨论】:

    标签: java design-patterns dependency-injection guice


    【解决方案1】:

    我是这个文档的作者。我称它为工厂是为了与 DocumentBuilderFactory 和 TransformerFactory 等 JDK 类保持一致。如果从未调用过 setInstance(),则该示例的先前版本返回默认实现:

      public static CreditCardProcessor getInstance() {
        if (instance == null) {
          return new SquareCreditCardProcessor();
        }
        return instance;
      }
    

    我对其进行了更改以避免工厂对其实现的编译时依赖性。该类具有 setInstance(),因为它比 JDK 用于在运行时选择实现的系统属性更简单。

    由于我们试图激发依赖注入,因此展示一个功能齐全的工厂似乎不公平,即使这意味着不忠于原始 GoF 模式。

    【讨论】:

    • 嗯,我真的不明白 Guice 的工厂与 DocumentBuilderFactory 是如何一致的,例如,它有一个工厂方法,但没有像 Guice 的情况下的 setInstance。 DocumentBuilderFactory 似乎更符合我认为的 GoF 模式。但我想你的帖子最能回答我的问题。
    • 嗯,我可以看到与 Guice 合作的人如何回想起 Guice 可以称其为工厂之前的过去。杰西,你为什么要选择一个单例的例子呢?它只是让每个人都感到困惑。
    【解决方案2】:

    我使用了类似的模式,可以根据上下文为代码赋予不同的类来执行某些操作。例如,如果 CreditCardProcessor 是一个接口或抽象类,高级代码希望通过创建它并将其传递给 CreditCardProcessorFactory 来设置要使用的实现。使用代码只是得到一个 CreditCardProcessor 而不关心它是什么实现。

    这与工厂模式很相似,因为你得到一个 CreditCardProcessor 而不关心你有哪个实现;您只是没有将任何参数传递给工厂方法(在这种情况下名为 getInstance() )。您获得的实现取决于其他代码设置的内容,而不是您指定的参数。在这种情况下,我什至可能已经将我实现的类称为工厂。

    getInstance() 和 setInstance() 是不好的名字,因为它们会让你想到单例。我会选择 getCreditCardProcessor 和 setCreditCardProcessor。

    【讨论】:

      【解决方案3】:

      这可能只是一个简化。 Java 有一堆工厂类,它们的使用方式如下:

      Foo newFoo = FooFactory.getInstance().makeFoo();
      

      ...本质上与示例中的相同。是的,Guice 示例使用静态方法而不是来自单通方法的方法,但我们已经知道singletons are little more than a very roundabout way of making static methods and fields。我认为他们只是快速地展示了糟糕代码的外观,并且他们并不真正关心是否遵守 GoF 模式规范。

      【讨论】:

      • 在你提到的那些工厂类中,你必须先调用 setInstance(FooImpl) 吗?在 Guice 的示例中,注入了“creditCardProcessor”。
      • 我现在唯一能想到的类是DocumentBuilderFactory,它有一个稍微高级一点的方法来选择newInstance()(嗯,它几乎 @987654326 @ ;) 返回:java.sun.com/javase/6/docs/api/javax/xml/parsers/…
      【解决方案4】:

      是的,但没有任何防止实例化(私有构造函数),它也不完全遵循单例模式。

      让它在这里完整的代码...... :)

      【讨论】:

        猜你喜欢
        • 2011-01-05
        • 2014-01-14
        • 2012-11-25
        • 1970-01-01
        • 1970-01-01
        • 2011-05-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多