我从一个网站上阅读设计模式
在那里我读到工厂,工厂方法和抽象工厂,但他们是如此混乱,我不清楚的定义。根据定义
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方法允许类延迟实例化到子类
抽象工厂:提供一个接口,用于创建一系列相关或依赖的对象,而无需指定它们的具体类。
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:根据注释中的异议为抽象工厂提供精确的接口。
没有人引用过原书《设计模式:可重用的面向对象软件的元素》,这本书在“创建模式的讨论”一节的前两段给出了答案:
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设计模式
以下图片来自Vaskaran Sarcar的《c#设计模式》第二版:
1. 简单工厂模式
创建对象而不向客户端公开实例化逻辑。
SimpleFactory simpleFactory = new SimpleFactory();
IAnimal dog = simpleFactory.CreateDog(); // Create dog
IAnimal tiger = simpleFactory.CreateTiger(); // Create tiger
2. 工厂方法模式
定义一个用于创建对象的接口,但是让子类来决定实例化哪个类。
AnimalFactory dogFactory = new DogFactory();
IAnimal dog = dogFactory.CreateAnimal(); // Create dog
AnimalFactory tigerFactory = new TigerFactory();
IAnimal tiger = tigerFactory.CreateAnimal(); // Create tiger
3.抽象工厂模式(工厂中的工厂)
抽象工厂提供了创建一系列相关对象的接口,而无需显式地指定它们的类
IAnimalFactory petAnimalFactory = FactoryProvider.GetAnimalFactory("pet");
IDog dog = petAnimalFactory.GetDog(); // Create pet dog
ITiger tiger = petAnimalFactory.GetTiger(); // Create pet tiger
IAnimalFactory wildAnimalFactory = FactoryProvider.GetAnimalFactory("wild");
IDog dog = wildAnimalFactory .GetDog(); // Create wild dog
ITiger tiger = wildAnimalFactory .GetTiger(); // Create wild tiger