如果我在实现工厂模式时使用抽象 class 而不是接口。还会是工厂模式吗?

If I use abstract class instead of interface while implementing factory pattern. Would it still be a factory pattern?

例如:http://www.tutorialspoint.com/design_pattern/factory_pattern.htm

如果我更改抽象 class Shape 上的接口形状,请创建具体 classes 以扩展 Shape 并创建 Shape 工厂 return Shape 抽象 class 类型对象。还会是工厂模式吗?

当涉及到这些差异时,答案总是肯定和否定。设计模式不是任何一种精确的规范,它们更像是一组最佳和推荐的实践,它们的实施因情况而异。

在我看来答案是否定的,从技术上讲这不是工厂模式。它不一定是,只要它解决了您的用例并使代码可读和可维护(试图从字面上遵守设计模式通常会导致滥用它们和过度架构)。

如果我们查看抽象工厂模式(链接页面中工厂模式的正下方),我们会看到它是用于创建工厂的工厂。现在假设我们有两个可以由 AbstractFactory 创建的 Shape 工厂:ShapeFactory2DShapeFactory3D,它们都生产 Shape 个对象。

如果 Shape 是抽象的 class,那么您将强制 2D 和 3D 对象继承相同的实现,尽管这可能没有任何意义(它们可以以完全不同的方式实现) .

因此,从技术上讲,为了使其成为真正的工厂模式,必须不存在关于实现细节的假设,这意味着不应在工厂接口级别使用包含部分实现的抽象 classes .

当然你可以让Abstract2DShapeAbstract3DShape抽象classes实现Shape;关键是您可以 createuse Shape 而不知道它是 2D 还是 3D 形状。

我同意。

让我们看一下工厂方法模式的定义:

the factory method pattern is a creational pattern which uses factory methods to deal with the problem of creating objects without specifying the exact class of object that will be created

此模式背后的动机是将对象创建与使用该对象的客户端分开。客户应向工厂提供规范,但详细说明对象的构建方式已被工厂抽象出来。

如果这是一个接口或抽象 class 是特定情况下的实现细节,只要您的工厂实现能让您实现模式背后的动机。

如果以下任何陈述适用于您的情况,请考虑使用摘要 classes:

  • You want to share code among several closely related classes.

  • You expect that classes that extend your abstract class have many common methods or fields, or require access modifiers other than public (such as protected and private).

  • You want to declare non-static or non-final fields. This enables you to define methods that can access and modify the state of the object to which they belong.

如果以下任何陈述适用于您的情况,请考虑使用接口:

  • You expect that unrelated classes would implement your interface. For example, the interfaces Comparable and Cloneable are implemented by many unrelated classes.

  • You want to specify the behavior of a particular data type, but not concerned about who implements its behavior.

  • You want to take advantage of multiple inheritance of type.

在某些实现中,对工厂创建的产品使用抽象 class 而不是接口甚至可能更有意义。如果所有产品之间存在共享的 features/behavior 集,那么将它们放入基础摘要 class 中确实有意义。即使产品来自不同的工厂,这也适用。

归结为:你想引入耦合吗?引入耦合是否有意义? 产品与否? 最终,客户将得到相同的结果——根据规范构建产品,抽象出构建细节。