为什么工厂方法是一种类模式,而抽象工厂是一种对象模式?

9

从GOF书中:

类模式处理类与其子类之间的关系。这些关系是通过继承建立的,因此它们在编译时是静态固定的。 对象模式处理对象关系,这些关系可以在运行时更改,更加动态。几乎所有模式都在一定程度上使用继承。因此,唯一标记为“类模式”的模式是那些专注于类关系的模式。

为什么工厂方法是一个类模式,而抽象工厂是一个对象模式,尽管它们似乎是非常相似的模式?

谢谢。


你为什么认为它们是相似的?因为它们都与工厂有关吗?它们根本不相似。 - MarcG
他们确实在做同样的工作。 - Mikhail Karakulov
3个回答

2

工厂方法模式和抽象工厂模式在意图上类似,但在实现上有着很大的区别(甚至可以说相反)。换句话说,这些模式代表了解决同一问题(实例化)的不同方式。

GOF说:

我们通过两个标准对设计模式进行分类。第一个标准称为目的,反映了模式的作用。

由于它们的意图相似(即它们具有相同的目的),因此这两种模式都被归类为创建型模式

GOF接着说:

第二个标准称为范围,指定模式是主要适用于类还是对象。

这就导致了引用OP的语句,其中类和对象范围各自被定义。因为工厂方法模式的实现侧重于继承(类关系),而抽象工厂模式的实现侧重于组合(对象关系),因此这两种模式被归类为相反的范围。

这两种模式的定义和实现可以在其他SO线程中找到,因此我在此不会重复。我也在其他地方讨论了这两种模式之间的组合与继承问题。


1
工厂模式可能更适合放在自己的类别中。但是对象/类分割背后的逻辑可能非常简单。工厂方法在其最小形式中是静态的(不可配置),就像类一样。但抽象工厂产生的结果(它们生成的对象)类取决于某些输入数据,并且由于它是动态效果,因此应将其放入对象模式类别中。

谢谢。你能举几个例子来解释一下吗? - Tim

1
《设计模式》这本书说:
意图:定义一个用于创建对象的接口,但让子类决定实例化哪个类。
这是什么意思?让我们看一下书中展示的例子。

Design patterns, GOF - Factory Method

在这个例子中,一个框架定义了Application接口,让其他人实现它。这意味着我可以像这样实现MyApplicationMyOtherApplication
public class MyApplication extends Application {
    protected Document createDocument() {
        return new MyDocument();
    }
}


public class MyOtherApplication extends Application {
    protected Document createDocument() {
        return new MyOtherDocument();
    }
}

当框架启动时,它可能根据类路径上的内容选择这些实现之一。
但这意味着,在框架实例化MyApplicationMyOtherApplication之后,创建文档的方式就被固定下来了。对于Application实例,在运行时无法再更改创建文档的方式。没有任何setter或其他东西可以用来改变Document的创建方式。因此,它也被称为虚拟构造函数,因此是一个类模式

抽象工厂

与工厂方法相反,抽象工厂可以在运行时更改,从而改变它创建的对象的方式。这就是为什么他们说它是一个对象模式的原因。
抽象工厂还负责创建

...相关或依赖对象的系列...

这也是与工厂方法aka.虚拟构造函数的区别之一。

谢谢。当我尝试将类/对象模式的概念应用于任何模式(不仅仅是工厂方法和抽象工厂)时,我又感到困惑了。https://stackoverflow.com/questions/56519548/how-shall-i-tell-if-a-design-pattern-is-a-class-pattern-or-an-object-pattern - Tim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接