设计模式:抽象工厂与工厂方法

141 language-agnostic uml design-patterns factory-method abstract-factory

注意:问题在帖子的末尾.

我已经阅读了有关Abstract Factory vs Factory Method的其他stackoverflow线程.我理解每个模式的意图.但是,我不清楚这个定义.

Factory方法定义了一个用于创建对象的接口,但是让子类决定实例化哪些接口.工厂方法允许类将实例化延迟到子类.

相比之下,抽象工厂提供了一个接口,用于创建相关或从属对象的族,而无需指定其具体类.

- John Feminella

抽象工厂看起来非常相似的工厂方法.我已经绘制了一些UML类来说明我的观点.

注意:

  • 该图来自www.yuml.com,因此它们并不完美.但它是免费服务:).
  • 图表可能不完美.我还在学习GoF设计模式.

工厂方法:

工厂方法

抽象工厂(仅1名成员):

抽象工厂(仅1名成员)

抽象工厂(更多成员):

替代文字

问题:

  1. 如果抽象工厂只有一个创建者和一个产品,它仍然是抽象工厂模式吗?(创建家庭的界面)
  2. 可以从接口创建Factory Method具体创建者还是必须来自类?(类推迟实例化到子类)
  3. 如果抽象工厂只能有一个创建者和一个产品,那么抽象工厂工厂方法之间的唯一区别是前者的创建者是一个接口而后者的创建者是一个类?

小智 133

希望这可以帮助.它描述了各种类型的工厂.我使用Head First Design Patterns作为我的参考.我用yuml.me来图表.

静电厂

是一个带有静态方法的类,用于生成各种子类型的Product.

静电厂

简单的工厂

是一个可以生成各种子类型的产品的类.(它比静态工厂更好.当添加新类型时,基本Product类不需要仅更改Simple Factory Class)

简单的工厂

工厂方法

包含一种生成与其类型相关的产品类型的方法.(它比Simple Factory更好,因为类型被推迟到子类.)

工厂方法

抽象工厂

生成相关的类型系列.它与工厂方法明显不同,因为它有多种类型的方法.(这很复杂,请参考下图以获得更好的实际示例).

抽象工厂

.NET Framework中的示例

DbFactoriesProvider是一个简单工厂,因为它没有子类型.DbFactoryProvider是一个抽象工厂,因为它可以创建各种相关的数据库对象,如连接和命令对象.

从.NET Framework抽象工厂

  • 如果在Factory Method的情况下,只有`Product`(作为抽象),然后`Product1`和`Product2`,作为儿子,难道不是更清楚吗?这有助于Factory Method只是创建一个产品,而Abstract Factory或多或少是一堆工厂方法在家庭中聚集在一起. (4认同)

Don*_*oby 78

这两种模式肯定是相关的!

模式之间的差异通常是故意的.

意向工厂方法是"定义一个接口用于创建对象,让子类决定将哪一个类实例.工厂方法使一个类的实例化延迟到子类."

意图抽象工厂是"用于创建相关或依赖的对象,而无需指定它们具体的类提供一个接口."

纯粹基于这些意图陈述(引自GoF),我会说,确实工厂方法在某种意义上是一个"退化" 抽象工厂,其中包含一个家族.

它们通常在实现上有所不同,因为Factory MethodAbstract Factory简单得多.

然而,它们也与实施有关.正如GoF书中所述,

AbstractFactory仅声明用于创建产品的接口.由ConcreteProduct子类实际创建它们.最常见的方法是为每个产品定义工厂方法.

这个c2 wiki也有一些关于这个主题的有趣讨论.

  • 我既不理解评论,也不理解downvote.你能详细说说吗? (7认同)

jac*_*646 13

似乎OP的(优秀)问题列表被忽略了.目前的答案仅提供重新定义的定义.因此,我将简要地尝试解决原始问题.

  1. 如果抽象工厂只有一个创建者和一个产品,它仍然是抽象工厂模式吗?(创建家庭的界面)

.抽象工厂必须创建多个产品才能构成"相关产品系列".规范的GoF示例创建ScrollBar()Window().优点(和目的)是抽象工厂可以在其多个产品中实施共同主题.

  1. 可以从接口创建Factory Method具体创建者还是必须来自类?(类推迟实例化到子类)

首先,我们必须注意,当GoF写下他们的书时,Java和C#都不存在.GoF对术语接口的使用与特定语言引入的接口类型无关.因此,可以从任何API创建具体创建者.模式中的重点是API使用自己的工厂方法,因此只有一个方法的接口不能是工厂方法,它可以是一个抽象工厂.

  1. 如果抽象工厂只能有一个创建者和一个产品,那么抽象工厂工厂方法之间的唯一区别是前者的创建者是一个接口而后者的创建者是一个类?

根据上述答案,此问题不再有效; 但是,如果您认为抽象工厂和工厂方法之间的唯一区别是创建的产品数量,请考虑客户端如何使用这些模式.抽象工厂通常被注入其客户端并通过组合/委托调用.必须继承工厂方法.所以这一切都回到了旧的构成与继承辩论.

但这些答案提出了第四个问题!

  1. 因为,只有一个方法的接口不能是一个工厂方法,它可以是一个抽象工厂,我们称之为只有一个方法的创建接口?

如果方法是静态的,则通常称为静态工厂.如果该方法是非静态的,则通常称为简单工厂.这些都不是GoF模式,但在实践中它们更常用!

  • @georaldc,来自 GoF(第 107 页)“_Factory Method 让类将实例化推迟到子类。_”换句话说,Factory Method 根据定义使用继承。 (2认同)