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

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

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示例吗?


当前回答

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:根据注释中的异议为抽象工厂提供精确的接口。

其他回答

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

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

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

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

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

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

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

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:根据注释中的异议为抽象工厂提供精确的接口。

所有三种Factory类型都做同样的事情:它们是一个“智能构造函数”。

假设您希望能够创建两种水果:Apple和Orange。

工厂

Factory is "fixed", in that you have just one implementation with no subclassing. In this case, you will have a class like this:
class FruitFactory {

  public Apple makeApple() {
    // Code for creating an Apple here.
  }

  public Orange makeOrange() {
    // Code for creating an orange here.
  }

}

用例:在构造函数中构造Apple或Orange都太复杂了。

工厂方法

Factory method is generally used when you have some generic processing in a class, but want to vary which kind of fruit you actually use. So:
abstract class FruitPicker {

  protected abstract Fruit makeFruit();

  public void pickFruit() {
    private final Fruit f = makeFruit(); // The fruit we will work on..
    <bla bla bla>
  }
}

...然后你可以通过在子类中实现一个工厂方法来重用fruitpick . pickfruit()中的通用功能:

class OrangePicker extends FruitPicker {

  @Override
  protected Fruit makeFruit() {
    return new Orange();
  }
}

抽象工厂

Abstract factory is normally used for things like dependency injection/strategy, when you want to be able to create a whole family of objects that need to be of "the same kind", and have some common base classes. Here's a vaguely fruit-related example. The use case here is that we want to make sure that we don't accidentally use an OrangePicker on an Apple. As long as we get our Fruit and Picker from the same factory, they will match.
interface PlantFactory {
  
  Plant makePlant();

  Picker makePicker(); 

}

public class AppleFactory implements PlantFactory {
  Plant makePlant() {
    return new Apple();
  }

  Picker makePicker() {
    return new ApplePicker();
  }
}

public class OrangeFactory implements PlantFactory {
  Plant makePlant() {
    return new Orange();
  }

  Picker makePicker() {
    return new OrangePicker();
  }
}
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对象

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

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

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

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

工厂方法(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.