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

注意:问题在帖子末尾。

我已阅读关于抽象工厂vs工厂方法的其他stackoverflow线程。 我理解每种模式的意图。 但是,我不清楚这个定义。

Factory Method定义了一个用于创建对象的接口,但可以让子类决定实例化哪些接口。 工厂方法让类将实例化推迟到子类。

相比之下,抽象工厂提供了一个界面,用于创建相关或依赖对象的族,而无需指定具体的类。

- 约翰Feminella

抽象工厂看起来与工厂方法非常相似。 我画了几个UML类来说明我的观点。

注意:

  • 该图来自www.yuml.com,因此它们并不完美。 但它的免费服务:)。
  • 图表可能不完美。 我仍然在学习GoF设计模式。
  • 工厂方法:

    工厂方法

    抽象工厂(只有1个成员):

    抽象工厂(只有1个成员)

    抽象工厂(更多成员):

    替代文字

    问题:

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

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

    静态工厂

    是具有静态方法的类来生成各种子类型的产品。

    静态工厂

    简单的工厂

    是可以生成各种子类型产品的类。 (它比静态工厂好,当添加新类型时,基本产品类不需要只改变简单工厂类)

    简单的工厂

    工厂方法

    包含一种生成与其类型相关的一种产品的方法。 (它比简单工厂要好,因为类型被推迟到一个子类。)

    工厂方法

    抽象工厂

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

    抽象工厂

    来自.NET Framework的示例

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

    来自.NET Framework的抽象工厂


    这两种模式当然是相关的!

    模式之间的差异通常是有意的。

    Factory Method意图是“定义一个用于创建对象的接口,但让子类决定实例化哪个类。Factory Method让类将实例化推迟到子类。”

    抽象工厂目的是“提供一个接口,用于创建相关或依赖对象的族,而不指定具体的类。”

    纯粹基于这些意图陈述(引自GoF),我会说工厂方法在某种意义上来说是一个“退化”的抽象工厂,其中一个家族。

    他们通常倾向于在实现上有所不同,因为工厂方法抽象工厂简单得多。

    然而,它们在实施中也是相关的。 正如GoF书中指出的那样,

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

    这个c2维基对这个主题也有一些有趣的讨论。


    看来,OP的(优秀)问题清单已被忽略。 目前的答案仅提供重新定义。 所以我会试图简洁地回答最初的问题。

  • 如果抽象工厂只有一个创作者和一个产品,它仍然是抽象工厂模式吗? (创建家庭的界面)
  • 不是。抽象工厂必须创建多个产品才能生成“相关产品系列”。 规范的GoF示例创建ScrollBar()Window() 。 优点(和目的)是抽象工厂可以在其多个产品上实施一个共同的主题。

  • 工厂方法的具体创建者可以从接口创建吗?还是必须来自一个类? (类将实例化推迟到子类)
  • 首先,我们必须指出,当GoF写他们的书时,Java和C#都不存在。 GoF使用术语接口与特定语言引入的接口类型无关。 因此,具体创建者可以从任何API创建。 该模式中的重要一点是,API使用自己的Factory Method,因此只有一个方法的接口不能成为Factory Method以外的其他接口。

  • 如果抽象工厂只能有一个创建者和一个产品,那么抽象工厂工厂方法之间的唯一区别是,前者的创建者是一个接口,而后者的创建者是一个类?
  • 根据上面的答案,这个问题不再有效; 但是,如果您认为抽象工厂和工厂方法之间的唯一区别是创建的产品数量,请考虑客户端如何使用这些模式中的每一个。 通常将抽象工厂注入其客户端,并通过组合/委托进行调用。 工厂方法必须被继承。 所有这一切都回到了旧的组合与继承的辩论。

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

  • 因为只有一个方法的接口不能是一个Factory Method ,而只能是一个抽象工厂 ,我们只用一种方法称为创建接口?
  • 如果该方法是静态的,则通常称为静态工厂 。 如果该方法是非静态的,它通常被称为简单工厂 。 这些都不是GoF模式,但实际上它们更常用!

    链接地址: http://www.djcxy.com/p/50121.html

    上一篇: Design Patterns: Abstract Factory vs Factory Method

    下一篇: Why do we need Abstract factory design pattern?