【问题标题】:Why is factory method a class pattern, while an abstract factory an object pattern?为什么工厂方法是类模式,而抽象工厂是对象模式?
【发布时间】:2023-11-04 23:41:01
【问题描述】:

来自 GOF 书:

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

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

谢谢。

【问题讨论】:

  • 为什么你认为它们很相似?因为都跟工厂有关?它们根本不相似。
  • 他们确实在做同样的工作。

标签: oop design-patterns abstract-factory factory-method


【解决方案1】:

GOF 书说

意图

定义一个用于创建对象的接口,但让子类决定实例化哪个类。

这是什么意思?让我们看一下书中展示的例子。

在示例中,框架定义了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 的创建方式。因此它也被称为虚拟构造函数,因此它是一个类模式

抽象工厂

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

抽象工厂也负责创建

...相关或依赖对象的族...

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

【讨论】:

  • 谢谢。当我尝试将类/对象模式的概念应用于任何模式(不仅仅是工厂方法和抽象工厂)时,我又不清楚了。 *.com/questions/56519548/…
【解决方案2】:

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

【讨论】:

  • 谢谢。你能举一些例子解释一下吗?
【解决方案3】:

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

GoF 说,

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

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

GoF 继续说,

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

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

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

【讨论】: