我从一个网站上阅读设计模式

在那里我读到工厂,工厂方法和抽象工厂,但他们是如此混乱,我不清楚的定义。根据定义

Factory - Creates objects without exposing the instantiation logic to the client and Refers to the newly created object through a common interface. Is a simplified version of Factory Method Factory Method - Defines an interface for creating objects, but let subclasses to decide which class to instantiate and Refers to the newly created object through a common interface. Abstract Factory - Offers the interface for creating a family of related objects, without explicitly specifying their classes.

我还看了其他关于抽象工厂和工厂方法的stackoverflow线程,但那里绘制的UML图使我的理解更加糟糕。

有人能告诉我吗

这三种模式之间有什么不同? 什么时候用哪个? 如果可能的话,还有与这些模式相关的java示例吗?


当前回答

要回答这个问题,我可以参考《四人帮》一书。

书中没有“工厂”、“简单工厂”或“虚拟工厂”的定义。通常,当人们谈论“工厂”模式时,他们可能是在谈论创建类的特定对象的东西(但不是“构建器”模式);它们可能引用也可能不引用“工厂方法”或“抽象工厂”模式。任何人都可以实现“工厂”,但他不会,因为它不是一个正式的术语(请记住,一些人、公司、社区可以有自己的词汇表)。

本书只包含了“抽象工厂”和“工厂方法”的定义。

以下是书中的定义,并简要解释了为什么两者都如此令人困惑。我省略了代码示例,因为你可以在其他答案中找到它们:

工厂方法(GOF):定义一个用于创建对象的接口,但让子类来决定实例化哪个类。工厂方法允许类延迟实例化到子类。

抽象工厂(GOF):提供一个接口,用于创建相关或依赖的对象族,而无需指定它们的具体类。

Source of Confusion: Often, one can call a class that used in "Factory Method" pattern as "Factory". This class is abstract by definition. That's why it easy to call this class "Abstract Factory". But it's just the name of the class; you shouldn't confuse it with "Abstract Factory" pattern (class name != pattern name). The "Abstract Factory" pattern is different - it does not use an abstract class; it defines an interface (not necessarily a programming language interface) for creating parts of a bigger object or objects that are related to each other or must be created in a particular way.

其他回答

AbstractProductA, A1 and A2 both implementing the AbstractProductA
AbstractProductB, B1 and B2 both implementing the AbstractProductB

interface Factory {
    AbstractProductA getProductA(); //Factory Method - generate A1/A2
}

使用工厂方法,用户可以创建AbstractProductA的A1或A2。

interface AbstractFactory {
    AbstractProductA getProductA(); //Factory Method
    AbstractProductB getProductB(); //Factory Method
}

但是抽象工厂有不止一个工厂方法(例如:2个工厂方法),使用这些工厂方法它将创建对象/相关对象的集合。 使用抽象工厂,用户可以创建AbstractProductA, AbstractProductB的A1, B1对象

没有人引用过原书《设计模式:可重用的面向对象软件的元素》,这本书在“创建模式的讨论”一节的前两段给出了答案:

There are two common ways to parameterize a system by the classes of objects it creates. One way is to subclass the class that creates the objects; this corresponds to using the Factory Method (107) pattern. The main drawback of this approach is that it can require a new subclass just to change the class of the product. Such changes can cascade. For example, when the product creator is itself created by a factory method, then you have to override its creator as well. The other way to parameterize a system relies more on object composition: Define an object that’s responsible for knowing the class of the product objects, and make it a parameter of the system. This is a key aspect of the Abstract Factory (87), Builder (97), and Prototype (117) patterns. All three involve creating a new “factory object” whose responsibility is to create product objects. Abstract Factory has the factory object producing objects of several classes. Builder has the factory object building a complex product incrementally using a correspondingly complex protocol. Prototype has the factory object building a product by copying a prototype object. In this case, the factory object and the prototype are the same object, because the prototype is responsible for returning the product.

每个设计模式都努力确保编写的工作代码不受影响。我们都知道,一旦我们接触到工作代码,现有的工作流程中就会有缺陷,并且需要进行更多的测试以确保我们没有破坏任何东西。

工厂模式根据输入条件创建对象,从而确保你不需要编写如下代码:

 if (this) {
     create this kind of object 
 } else { 
     that kind of object 
 }

一个很好的例子就是旅游网站。旅游网站只能提供旅行(航班、火车、巴士)或/和提供酒店或/和提供旅游景点套餐。现在,当用户选择下一步时,网站需要决定需要创建什么对象。它是否也只创建travel或hotel对象?

现在,如果你设想在你的投资组合中添加另一个网站,并且你相信同样的核心可以被使用,例如,一个拼车网站,现在可以搜索出租车并在线支付,你可以在你的核心中使用一个抽象工厂。这样一来,你就可以再加入一个出租车和拼车工厂。

这两个工厂之间没有任何关系,所以把它们放在不同的工厂是一个很好的设计。

希望大家都明白了。再次研究这个网站,记住这个例子,希望它会有帮助。我真的希望我已经正确地表示了模式:)。

这三种模式之间有什么不同?

工厂:创建对象时不向客户端公开实例化逻辑。

工厂方法:定义用于创建对象的接口,但让子类决定实例化哪个类。Factory方法允许类延迟实例化到子类

抽象工厂:提供一个接口,用于创建一系列相关或依赖的对象,而无需指定它们的具体类。

AbstractFactory模式使用组合将创建对象的责任委托给另一个类,而Factory方法设计模式使用继承并依赖于派生类或子类来创建对象

什么时候用哪个?

工厂:客户端只需要一个类,并不关心它得到的是哪个具体实现。

工厂方法:客户端不知道在运行时需要创建哪些具体的类,而只是想获得一个能够完成这项工作的类。

AbstactFactory:当您的系统必须创建多个产品系列,或者您希望提供一个产品库而不公开实现细节时。

抽象工厂类通常用工厂方法实现。工厂方法通常在模板方法中调用。

如果可能的话,还有与这些模式相关的java示例吗?

Factory和FactoryMethod

目的:

定义一个用于创建对象的接口,但是让子类来决定实例化哪个类。工厂方法允许类延迟实例化到子类。

UML diagram:

Product:它定义Factory方法创建的对象的接口。

ConcreteProduct:实现Product接口

创建者:声明Factory方法

ConcreateCreator:实现Factory方法以返回ConcreteProduct的实例

问题陈述:使用定义游戏界面的工厂方法创建游戏工厂。

代码片段:

工厂模式。什么时候使用工厂方法?

与其他创造模式的比较:

设计开始时使用工厂方法(不太复杂,更可定制,子类激增),然后随着设计师发现需要更多灵活性的地方,逐步向抽象工厂、原型或构建器发展(更灵活,更复杂) 抽象工厂类通常使用工厂方法来实现,但它们也可以使用原型来实现

进一步阅读的参考资料:Sourcemaking设计模式

Factory -分离Factory类来创建复杂的对象。

例如:FruitFactory类来创建Fruit对象

class FruitFactory{

public static Fruit getFruit(){...}

}

工厂方法——不需要为工厂添加一个单独的类,只需在类中添加一个方法作为工厂。

Ex:

Calendar.getInstance() (Java's Calendar)

抽象工厂——工厂中的工厂

比方说,我们想建一家生产电脑零件的工厂。有几种类型的电脑,如笔记本电脑,台式电脑,服务器。

所以对于每一种计算机类型,我们都需要工厂。所以我们创建了一个高级的工厂中的工厂,如下所示

ComputerTypeAbstractFactory.getComputerPartFactory(String computerType) ---> This will return PartFactory which can be one of these ServerPartFactory, LaptopPartFactory, DesktopPartFactory.

现在这3家公司本身也是工厂。(您将处理PartFactory本身,但在底层,将有基于您在抽象工厂中提供的内容的单独实现)

  Interface-> PartFactory. getComputerPart(String s), 
Implementations -> ServerPartFactory, LaptopPartFactory, DesktopPartFactory.

Usage:
new ComputerTypeAbstractFactory().getFactory(“Laptop”).getComputerPart(“RAM”)

EDIT:根据注释中的异议为抽象工厂提供精确的接口。