2010-12-02 155 views
18

我试图简洁地描述使用工厂,为我和我的团队。何时使用抽象工厂模式?

基于这些链接,和一堆其他来源(在底部列出),我想出了以下内容:

当使用抽象工厂模式:

    当你使用一个接口VAR或 '新' 运营商
    • 例如User user = new ConcreteUserImpl();在某些时候
  • 和你正在写的代码应该是可测试/扩展

说明:

  • 接口,通过其本身的性质意味着多种实现(便于进行单元测试)
  • 接口变量暗示符合OCP和LSP的代码(支持子分类)
  • 使用“新”运营商的突破OCP/DI,因为高度耦合的类很难检测或更改

“难道我创建的每个对象类型的工厂?这似乎过分。“

  • 没有,你可以有一个(或几个)产生了大量的(通常是相关的)对象类型
  • 如appFactory.createUser()的工厂; appFactory.createCatalog();等

当不使用厂家:

  • 新的对象是非常简单的,不太可能是子类
    • 例如List list = new ArrayList();
  • 新的对象是不感兴趣的测试
    • 没有依赖性
    • 执行没有相关的或长期运行工作
    • 例如Logger log = new SimpleLogger();

参考文献:


我的问题是:是我的总结准确,是否有意义?有什么我忽略了吗?

在此先感谢。

+1

这个Java为什么相关?它不应该是语言不可知的吗? – 2010-12-02 03:07:02

+0

@ the_drow:固定,谢谢。 – Luke 2010-12-02 18:17:56

+0

我讨厌振兴老话题,但是... 我不同意记录器应该像上面那样新建起来。我经常在不同的测试环境中运行不同的记录器。我将环境配置为使用特定的记录器并将其注入到记录的对象中。 (我甚至可能会注入数组记录器。) – aridlehoover 2013-03-19 23:35:03

回答

1

抽象工厂模式提供了一种方法来封装具有相同共同性的具体工厂,这意味着它们实现相同的接口/抽象类。

无论何时您想要控制对象的初始化,都需要使用工厂模式,而不是将控制权交给使用者。

5

我也想说当你有一个特定的实现你想要的时候不要使用工厂。要继续List示例,我知道我想要一个ArrayList,因为我正在进行随机访问。当我可以自己做这件事情时,我不想依赖一家工厂来做这件事。相反,当我不想知道具体的子类时,我可以使用工厂,让它担心实际实例化哪个对象。

我想我会建议你在“什么时候使用抽象工厂模式”中添加一个项目符号,它表示“你并不关心你获得哪个具体的子类”,并且相反地“使用工厂“。

编辑:小心避免general-purpose tool-building factory factory factory

3

通常,当您希望能够通过外部配置切换实施时使用它。

JDBC和JAXP是很好的例子。有关更多示例,请检查this answer