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

Why is factory method a class pattern, while an abstract factory an object pattern?

来自 GOF 书:

Class patterns deal with relationships between classes and their subclasses. These relationships are established through inheritance, so they are static-fixed at compile-time. Object patterns deal with object relationships, which can be changed at run-time and are more dynamic. Almost all patterns use inheritance to some extent. So the only patterns labeled "class patterns" are those that focus on class relationships.

为什么工厂方法是一个 class 模式,而抽象工厂是一个对象模式,因为它们看起来非常相似?

谢谢。

工厂模式最好放在自己的类别中。但是 object/class 除法背后的逻辑可能很简单。最小形式的工厂方法是静态的(不可配置的),就像 classes 一样。但是抽象工厂结果(他们生产的对象)class依赖于一些输入数据,并且由于它是动态效果,所以应该放在对象模式类别中。

GOF 书说

Intent

Define an interface for creating an object, but let subclasses decide which class to instantiate.

这是什么意思?我们来看书上的例子

在示例中,框架定义了 Application 接口以供其他人实现。这意味着我可以实现例如MyApplicationMyOtherApplication 像这样:

public class MyApplication extends Application {
    protected Document createDocument() {
        return new MyDocument();
    }
}


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

当框架启动时,它可能会根据在 class 路径上找到的内容选择这些实现之一。

但这意味着在框架实例化 MyApplicationMyOtherApplication 之后,文档的创建方式是固定的。 Application 实例的文档创建方式在运行时无法再更改没有 setter 或任何其他东西 可用于更改 Document 的创建方式。因此它也被称为 虚拟构造函数 因此它是一个 class 模式 .

抽象工厂

与工厂方法相比,抽象工厂可以在运行时更改,从而改变它创建对象的方式。这就是为什么他们说它是 对象模式.

一个抽象工厂也负责创建

... families of related or dependent objects ...

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

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

GoF 说,

We classify design patterns by two criteria. The first criterion, called purpose, reflects what a pattern does.

因为他们的意图相似(即他们有相同的目的)这两个模式都class化为创作

GoF 继续说,

The second criterion, called scope, specifies whether the pattern applies primarily to classes or to objects.

这引出了来自 OP 的引用,其中分别定义了 class 和对象范围。由于工厂方法的实现侧重于继承(class 关系),而抽象工厂的实现侧重于组合(对象关系),这两种模式在相反的范围内class化。

这两种模式的定义和实现可以在很多其他SO线程中找到,这里不再赘述。我还谈到了这两种模式中的组合与继承问题elsewhere