抽象工厂和工厂设计模式有什么区别?
我知道有很多关于这两种模式之间差异的帖子,但有一些东西我找不到。
从我读到的内容来看,我发现工厂方法模式允许您定义如何创建单个具体产品,但对客户端隐藏实现,因为他们将看到通用产品。我的第一个问题是关于抽象工厂的。它的作用是允许您创建一系列具体对象(这可能取决于您使用的特定工厂)而不仅仅是单个具体对象?抽象工厂是否只返回一个非常大的对象或许多对象,具体取决于您调用的方法?
我的最后两个问题是关于我在很多地方看到的一个我无法完全理解的单引号:
两者之间的一个区别是 使用抽象工厂模式, 班级代表的责任 对象实例化到另一个对象 通过组合,而工厂 方法模式使用继承和 依赖子类来处理 所需的对象实例化。
我的理解是工厂方法模式有一个 Creator 接口,它将使 ConcreteCreator 负责知道要实例化哪个 ConcreteProduct。这就是使用继承来处理对象实例化的意思吗?
现在,关于那句话,抽象工厂模式究竟如何通过组合将对象实例化的责任委托给另一个对象?这意味着什么?在我看来,抽象工厂模式也使用继承来完成构建过程,但话又说回来,我仍在学习这些模式。
任何帮助,特别是最后一个问题,将不胜感激。
I know there are many posts out there about the differences between these two patterns, but there are a few things that I cannot find.
From what I have been reading, I see that the factory method pattern allows you to define how to create a single concrete product but hiding the implementation from the client as they will see a generic product. My first question is about the abstract factory. Is its role to allow you to create families of concrete objects in (that can depend on what specific factory you use) rather than just a single concrete object? Does the abstract factory only return one very large object or many objects depending on what methods you call?
My final two questions are about a single quote that I cannot fully understand that I have seen in numerous places:
One difference between the two is that
with the Abstract Factory pattern, a
class delegates the responsibility of
object instantiation to another object
via composition whereas the Factory
Method pattern uses inheritance and
relies on a subclass to handle the
desired object instantiation.
My understanding is that the factory method pattern has a Creator interface that will make the ConcreteCreator be in charge of knowing which ConcreteProduct to instantiate. Is this what it means by using inheritance to handle object instantiation?
Now with regards to that quote, how exactly does the Abstract Factory pattern delegate the responsibility of object instantiation to another object via composition? What does this mean? It looks like the Abstract Factory pattern also uses inheritance to do the construction process as well in my eyes, but then again I am still learning about these patterns.
Any help especially with the last question, would be greatly appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(21)
两者的区别
“工厂方法”和“抽象工厂”之间的主要区别在于,工厂方法是方法,而抽象工厂是对象。我认为很多人混淆了这两个术语,并开始互换使用它们。我记得当我学习它们时,我很难准确地找出它们之间的区别。
因为工厂方法只是一个方法,所以可以在子类中重写它,因此引用的后半部分:
引用假设一个对象正在调用它自己的工厂方法。因此,唯一可以改变返回值的是子类。
抽象工厂是一个具有多个工厂方法的对象。看看你引用的前半部分:
他们所说的是有一个对象 A,他想要创建一个 Foo 对象。它将获取一个不同的对象(抽象工厂)来创建 Foo 对象,而不是创建 Foo 对象本身(例如,使用工厂方法)。
代码示例
为了向您展示差异,这里是正在使用的工厂方法:
这是正在使用的抽象工厂:
The Difference Between The Two
The main difference between a "factory method" and an "abstract factory" is that the factory method is a method, and an abstract factory is an object. I think a lot of people get these two terms confused, and start using them interchangeably. I remember that I had a hard time finding exactly what the difference was when I learnt them.
Because the factory method is just a method, it can be overridden in a subclass, hence the second half of your quote:
The quote assumes that an object is calling its own factory method here. Therefore the only thing that could change the return value would be a subclass.
The abstract factory is an object that has multiple factory methods on it. Looking at the first half of your quote:
What they're saying is that there is an object A, who wants to make a Foo object. Instead of making the Foo object itself (e.g., with a factory method), it's going to get a different object (the abstract factory) to create the Foo object.
Code Examples
To show you the difference, here is a factory method in use:
And here is an abstract factory in use:
抽象工厂使用抽象方法创建一个基类,为应创建的对象定义方法。每个派生基类的工厂类都可以创建自己的每个对象类型的实现。
工厂方法只是一个简单的方法用于在类中创建对象。它通常添加在聚合根中(
Order
类有一个名为CreateOrderLine
的方法)抽象工厂
在下面的示例中,我们设计了一个接口,以便我们可以将队列创建与消息传递系统分离,从而可以为不同的队列系统创建实现,而无需更改代码库。
工厂方法
HTTP 服务器中的问题是我们总是需要对每个请求做出响应。
如果没有工厂方法,HTTP 服务器用户(即程序员)将被迫使用特定于实现的类,这违背了
IHttpRequest
接口的目的。因此,我们引入了工厂方法,以便将响应类的创建也抽象出来。
总结
区别在于,包含工厂方法的类的预期目的不是创建对象,而抽象工厂只能用于创建对象。
使用工厂方法时应该小心,因为很容易破坏 LSP (创建对象时的里氏替换原则)。
Abstract factory creates a base class with abstract methods defining methods for the objects that should be created. Each factory class which derives the base class can create their own implementation of each object type.
Factory method is just a simple method used to create objects in a class. It's usually added in the aggregate root (The
Order
class has a method calledCreateOrderLine
)Abstract factory
In the example below we design an interface so that we can decouple queue creation from a messaging system and can therefore create implementations for different queue systems without having to change the code base.
Factory method
The problem in HTTP servers is that we always need an response for every request.
Without the factory method, the HTTP server users (i.e. programmers) would be forced to use implementation specific classes which defeat the purpose of the
IHttpRequest
interface.Therefore we introduce the factory method so that the creation of the response class also is abstracted away.
Summary
The difference is that the intended purpose of the class containing a factory method is not to create objects, while an abstract factory should only be used to create objects.
One should take care when using factory methods since it's easy to break the LSP (Liskov Substitution principle) when creating objects.
AbstractFactory 和 Factory 设计模式之间的区别如下:
工厂方法模式实现:
抽象工厂模式实现: >
Difference between AbstractFactory and Factory design patterns are as follows:
Factory Method Pattern Implementation:
Abstract Factory Pattern Implementation:
Abstract Factory 和 Factory Method 的主要区别在于Abstract Factory 是通过 Composition 实现的;但是工厂方法是通过继承实现的。
是的,您没有看错:这两种模式之间的主要区别是旧的组合与继承辩论。
UML 图可以在 (GoF) 书中找到。我想提供代码示例,因为我认为结合本线程中前两个答案的示例将比单独的任何一个答案提供更好的演示。此外,我在类和方法名称中使用了书中的术语。
抽象工厂
被注入到客户端。这就是为什么我们说抽象
工厂是通过组合来实现的。通常,依赖注入
框架将执行该任务;但不需要框架
对于DI。
不是工厂方法实现!工厂的示例代码
下面进一步示出方法。
产品:在本例中为出站和回复队列。一混凝土
工厂生产Azure队列,另一个生产MSMQ。 GoF指的是
这种产品关系就像一个“家庭”,这一点很重要
请注意,这里的家庭并不意味着阶级等级制度。
工厂方法
ConcreteCreator
是客户。换句话说,客户端是一个子类,其父类定义了factoryMethod()。这就是为什么我们这么说
工厂方法是通过继承来实现的。
模式只不过是模板方法的特化
图案。这两种模式具有相同的结构。他们只
目的不同。工厂方法是创造性的(它构建
某事)而模板方法是行为性的(它计算
某物)。
Creator
(父级)类调用它自己的
factoryMethod()
。如果我们删除anOperation()
来自父类,只留下一个方法后面,就不再是Factory Method模式了。换句话说,
工厂方法不能用少于两个方法来实现
父类;并且一个必须调用另一个。
杂项。 &各种工厂模式
请注意,尽管 GoF 定义了两种不同的工厂模式,但它们并不是唯一存在的工厂模式。它们甚至不一定是最常用的工厂模式。第三个著名的例子是来自Effective Java 的Josh Bloch 的静态工厂模式。 《Head First Design Patterns》一书还包含另一种模式,他们称之为“简单工厂”。
不要陷入假设每个工厂模式都必须与 GoF 中的模式相匹配的陷阱。
The main difference between Abstract Factory and Factory Method is that Abstract Factory is implemented by Composition; but Factory Method is implemented by Inheritance.
Yes, you read that correctly: the main difference between these two patterns is the old composition vs inheritance debate.
UML diagrams can be found in the (GoF) book. I want to provide code examples, because I think combining the examples from the top two answers in this thread will give a better demonstration than either answer alone. Additionally, I have used terminology from the book in class and method names.
Abstract Factory
is injected into the client. This is why we say that Abstract
Factory is implemented by Composition. Often, a dependency injection
framework would perform that task; but a framework is not required
for DI.
not Factory Method implementations! Example code for Factory
Method is shown further below.
products: in this case the outbound and reply queues. One concrete
factory produces Azure queues, the other MSMQ. The GoF refers to
this product relationship as a "family" and it's important to be
aware that family in this case does not mean class hierarchy.
Factory Method
ConcreteCreator
is the client. In other words, the client is a subclass whose parent defines the
factoryMethod()
. This is why we say thatFactory Method is implemented by Inheritance.
Pattern is nothing more than a specialization of the Template Method
Pattern. The two patterns share an identical structure. They only
differ in purpose. Factory Method is creational (it builds
something) whereas Template Method is behavioral (it computes
something).
Creator
(parent)class invokes its own
factoryMethod()
. If we removeanOperation()
from the parent class, leaving only a single methodbehind, it is no longer the Factory Method pattern. In other words,
Factory Method cannot be implemented with less than two methods in
the parent class; and one must invoke the other.
Misc. & Sundry Factory Patterns
Be aware that although the GoF define two different Factory patterns, these are not the only Factory patterns in existence. They are not even necessarily the most commonly used Factory patterns. A famous third example is Josh Bloch's Static Factory Pattern from Effective Java. The Head First Design Patterns book includes yet another pattern they call Simple Factory.
Don't fall into the trap of assuming every Factory pattern must match one from the GoF.
Abstract Factory是用于创建相关产品的接口,而Factory Method只是一种方法。抽象工厂可以通过多个工厂方法来实现。
Abstract Factory is an interface for creating related products, but Factory Method is only one method. Abstract Factory can be implemented by multiple Factory Methods.
考虑这个例子以便于理解。
电信公司提供什么?例如,宽带、电话线和移动设备,您需要创建一个应用程序来向客户提供他们的产品。
一般来说,您在这里要做的是,通过您的工厂方法创建产品,即宽带、电话线和移动设备,您知道这些产品拥有哪些属性,而且非常简单。
现在,该公司希望向客户提供一系列产品,即宽带、电话线和移动设备,这就需要抽象工厂来发挥作用。
换句话说,抽象工厂是由其他工厂组成的,这些工厂负责创建自己的产品,并且抽象工厂知道如何将这些产品放在更有意义的方面其自身的责任。
在本例中,
BundleFactory
是抽象工厂,BroadbandFactory
、PhonelineFactory
和MobileFactory
是Factory
。为了更加简化,这些工厂将使用工厂方法来初始化各个产品。请参阅下面的代码示例:
希望这会有所帮助。
Consider this example for easy understanding.
What does telecommunication companies provide? Broadband, phone line and mobile for instance and you're asked to create an application to offer their products to their customers.
Generally what you'd do here is, creating the products i.e broadband, phone line and mobile are through your Factory Method where you know what properties you have for those products and it's pretty straightforward.
Now, the company wants to offer their customer a bundle of their products i.e broadband, phone line, and mobile altogether, and here comes the Abstract Factory to play.
Abstract Factory is, in other words, are the composition of other factories who are responsible for creating their own products and Abstract Factory knows how to place these products in more meaningful in respect of its own responsibilities.
In this case, the
BundleFactory
is the Abstract Factory,BroadbandFactory
,PhonelineFactory
andMobileFactory
are theFactory
. To simplify more, these Factories will have Factory Method to initialise the individual products.Se the code sample below:
Hope this helps.
工厂方法依赖于继承:对象创建委托给子类,子类实现工厂方法来创建对象。
抽象工厂依赖于对象组合:对象创建是在工厂接口中公开的方法中实现的。
工厂和抽象工厂模式的高级图,
有关工厂方法的更多信息,请参阅 本文。
有关抽象工厂方法的更多信息,请参阅本文。
Factory Method relies on inheritance: Object creation is delegated to subclasses, which implement the factory method to create objects.
Abstract Factory relies on object composition: object creation is implemented in methods exposed in the factory interface.
High level diagram of Factory and Abstract factory pattern,
For more information about the Factory method, refer this article.
For more information about Abstract factory method, refer this article.
现实生活中的例子。 (容易记住)
工厂
想象一下你正在建造一座房子,你向木匠寻求一扇门。您给出门的尺寸和您的要求,他将为您建造一扇门。在这种情况下,木匠是一家门工厂。您的规格是工厂的输入,而门是工厂的输出或产品。
抽象工厂
现在,考虑相同的门示例。你可以去找木匠,也可以去塑料门店或者PVC店。都是门厂。根据情况,您决定需要联系什么样的工厂。这就像一个抽象工厂。
我在这里解释了工厂方法模式和抽象工厂模式,首先不使用它们解释问题,然后使用上述模式解决问题
https://github.com/vikramnagineni/Design-Patterns/tree/master
Real Life Example. (Easy to remember)
Factory
Imagine you are constructing a house and you approach a carpenter for a door. You give the measurement for the door and your requirements, and he will construct a door for you. In this case, the carpenter is a factory of doors. Your specifications are inputs for the factory, and the door is the output or product from the factory.
Abstract Factory
Now, consider the same example of the door. You can go to a carpenter, or you can go to a plastic door shop or a PVC shop. All of them are door factories. Based on the situation, you decide what kind of factory you need to approach. This is like an Abstract Factory.
I have explained here both Factory method pattern and abstract factory pattern beginning with not using them explaining issues and then solving issues by using the above patterns
https://github.com/vikramnagineni/Design-Patterns/tree/master
那里有很多定义。基本上,描述工厂模式的三种常见方式是
下面的链接非常有用 - 工厂比较 - refactoring.guru
There are quite a few definitions out there. Basically, the three common way of describing factory pattern are
The below link was very useful - Factory Comparison - refactoring.guru
1.我的第一个问题是关于抽象工厂的。它的作用是允许您在其中创建一系列具体对象(这可能取决于您使用的特定工厂)而不仅仅是单个具体对象?
是的。抽象工厂的意图是:
2.抽象工厂是否只返回一个非常大的对象或许多对象,具体取决于您调用的方法?
理想情况下,它应该为客户端调用的每个方法返回一个对象。
3.我的理解是工厂方法模式有一个 Creator 接口,它将使 ConcreteCreator 负责知道要实例化哪个 ConcreteProduct。这就是使用继承来处理对象实例化的意思吗?
是的。工厂方法使用继承。
4。抽象工厂模式通过组合将对象实例化的责任委托给另一个对象?这是什么意思?
AbstractFactory 定义了一个 FactoryMethod,ConcreteFactory 负责构建一个 ConcreteProduct。
只需按照 James Sugrue 撰写的这篇 dzone 文章中的代码示例进行操作即可。
您可以在相关的 SE 帖子中找到更多详细信息:
工厂设计模式和抽象工厂设计模式之间的基本区别是什么?
设计模式:工厂与工厂方法与抽象工厂
1. My first question is about the abstract factory. Is its role to allow you to create families of concrete objects in (that can depend on what specific factory you use) rather than just a single concrete object?
Yes. The intent of Abstract Factory is:
2. Does the abstract factory only return one very large object or many objects depending on what methods you call?
Ideally it should return one object per the method client is invoking.
3. My understanding is that the factory method pattern has a Creator interface that will make the ConcreteCreator be in charge of knowing which ConcreteProduct to instantiate. Is this what it means by using inheritance to handle object instantiation?
Yes. Factory method uses inheritance.
4. Abstract Factory pattern delegate the responsibility of object instantiation to another object via composition? What does this mean?
AbstractFactory defines a FactoryMethod and ConcreteFactory is responsible for building a ConcreteProduct.
Just follow through the code example in this dzone article by by James Sugrue.
You can find more details in related SE posts:
What is the basic difference between the Factory and Abstract Factory Design Patterns?
Design Patterns: Factory vs Factory method vs Abstract Factory
了解动机的差异:
假设您正在构建一个工具,其中包含对象和对象相互关系的具体实现。由于您预见了对象的变化,因此您通过将创建对象变体的责任分配给另一个对象(我们称之为抽象工厂)来创建间接寻址。这种抽象具有很大的好处,因为您预见到未来的扩展需要这些对象的变体。
这种思路的另一个相当有趣的动机是整个组中的每个对象或没有一个对象将具有相应的变体。根据某些条件,将使用任一变体,并且在每种情况下所有对象都必须具有相同的变体。这可能有点违反直觉,因为我们通常倾向于认为 - 只要对象的变体遵循共同的统一契约(更广泛意义上的接口),具体的实现代码就永远不会中断。这里有趣的事实是,并不总是如此,特别是当预期行为无法通过编程契约建模时。
一个简单的例子(借用 GoF 的想法)是任何 GUI 应用程序,例如模拟 MS、Mac 或 Fedora 操作系统外观的虚拟监视器。在这里,例如,当所有窗口、按钮等小部件对象除了从MAC变体派生的滚动条之外都具有MS变体时,该工具的目的就严重失败了。
以上这些案例构成了抽象工厂模式的根本需求。
另一方面,假设您正在编写一个框架,以便许多人可以使用您的框架构建各种工具(例如上面示例中的工具)。根据框架的想法,您不需要这样做,尽管您不能在逻辑中使用具体对象。您宁愿在各种对象之间以及它们的交互方式之间放置一些高级契约。虽然您(作为框架开发人员)仍处于非常抽象的级别,但该工具的每个构建者都被迫遵循您的框架构造。然而,他们(工具构建者)可以自由地决定要构建什么对象以及他们创建的所有对象如何交互。与前面的情况(抽象工厂模式)不同,您(作为框架创建者)在这种情况下不需要使用具体对象;而可以停留在对象的契约级别。此外,与前面动机的第二部分不同,您或工具构建者永远不会遇到混合来自变体的对象的情况。在这里,虽然框架代码仍处于合同级别,但每个工具构建者都受到限制(受案例本身的性质)使用自己的对象。在这种情况下,对象创建被委托给每个实现者,框架提供者只提供用于创建和返回对象的统一方法。这些方法对于框架开发人员继续他们的代码是不可避免的,并且有一个特殊的名称,称为工厂方法(底层模式的工厂方法模式)。
一些注释:
示例代码:
Understand the differences in the motivations:
Suppose you’re building a tool where you’ve objects and a concrete implementation of the interrelations of the objects. Since you foresee variations in the objects, you’ve created an indirection by assigning the responsibility of creating variants of the objects to another object (we call it abstract factory). This abstraction finds strong benefit since you foresee future extensions needing variants of those objects.
Another rather intriguing motivation in this line of thoughts is a case where every-or-none of the objects from the whole group will have a corresponding variant. Based on some conditions, either of the variants will be used and in each case all objects must be of same variant. This might be a bit counter intuitive to understand as we often tend think that - as long as the variants of an object follow a common uniform contract (interface in broader sense), the concrete implementation code should never break. The intriguing fact here is that, not always this is true especially when expected behavior cannot be modeled by a programming contract.
A simple (borrowing the idea from GoF) is any GUI applications say a virtual monitor that emulates look-an-feel of MS or Mac or Fedora OS’s. Here, for example, when all widget objects such as window, button, etc. have MS variant except a scroll-bar that is derived from MAC variant, the purpose of the tool fails badly.
These above cases form the fundamental need of Abstract Factory Pattern.
On the other hand, imagine you’re writing a framework so that many people can built various tools (such as the one in above examples) using your framework. By the very idea of a framework, you don’t need to, albeit you could not use concrete objects in your logic. You rather put some high level contracts between various objects and how they interact. While you (as a framework developer) remain at a very abstract level, each builders of the tool is forced to follow your framework-constructs. However, they (the tool builders) have the freedom to decide what object to be built and how all the objects they create will interact. Unlike the previous case (of Abstract Factory Pattern), you (as framework creator) don’t need to work with concrete objects in this case; and rather can stay at the contract level of the objects. Furthermore, unlike the second part of the previous motivations, you or the tool-builders never have the situations of mixing objects from variants. Here, while framework code remains at contract level, every tool-builder is restricted (by the nature of the case itself) to using their own objects. Object creations in this case is delegated to each implementer and framework providers just provide uniform methods for creating and returning objects. Such methods are inevitable for framework developer to proceed with their code and has a special name called Factory method (Factory Method Pattern for the underlying pattern).
Few Notes:
Sample Code:
工厂设计模式
工厂
用例:实例化
第2代
的一个对象它是一个
创意 模式允许您在一个简单的地方创建
第二代
。它符合 SRP 和 OCP - 所有更改都在单个类中进行。工厂方法
用例:实例化
第3代
的一个对象有助于与下一代家庭成员合作。每个画家都有自己的风格,比如印象派、超现实主义……
Factory Method
使用抽象的Creator
作为Factory(抽象方法)和Concrete Creators
的实现此方法的抽象工厂
用例:实例化
第3代
的所有对象工厂
是抽象的一部分Factory
和Concrete Factories
中的实现Factory Design Pattern
Factory
Use case: instantiate one object of
generation 2
It is a
Creational
pattern which allows you to creategeneration 2
in a simple place. It conforms SRP and OCP - all changes are made in a single class.Factory method
Use case: instantiate one object of
generation 3
Helps to work with next generation of family members. Every painter has his own style like Impressionism, Surrealism...
Factory Method
uses abstractCreator
as Factory(abstract method) andConcrete Creators
are realizations of this methodAbstract Factory
Use case: instantiate all objects of
generation 3
Factory
is a part of abstractFactory
and realisations inConcrete Factories
让我们明确一点,在生产代码中,大多数时候,我们使用抽象工厂模式,因为类 A 使用接口 B 进行编程。并且 A 需要创建 B 的实例。因此 A 必须有一个工厂对象来生成 B 的实例所以 A 不依赖于 B 的任何具体实例。希望它有帮助。
Let us put it clear that most of the time in production code, we use abstract factory pattern because class A is programmed with interface B. And A needs to create instances of B. So A has to have a factory object to produce instances of B. So A is not dependent on any concrete instance of B. Hope it helps.
以最少的界面和简单的方式使其变得非常简单请关注“//1”:
这里重点: 1.工厂& AbstractFactory机制必须使用继承(System.Object->byte、float...);所以如果你在程序中有继承,那么工厂(抽象工厂很可能不会在那里)已经被设计为2。创建者(MyFactory)知道具体类型,因此将具体类型对象返回给调用者(Main);在抽象工厂中,返回类型将是一个接口。
要点: 1. 要求:本田将创建“Regular”、“Sports”,而 Hero 将创建“DarkHorse”、“Sports”和“Scooty”。 2.为什么有两个接口?一个用于制造商类型(IVehicleFactory),另一个用于产品工厂(IVehicle);理解 2 个接口的另一种方式是抽象工厂就是创建相关对象 2。 问题是 IVehicleFactory 的子级返回 IVehicle(而不是工厂中的具体对象);所以我得到父变量(IVehicle);然后我通过调用 CreateSingleVehicle 创建实际的具体类型,然后将父对象转换为实际的子对象。如果我这样做
RegularBike HeroRegularBike = (RegularBike)hero.CreateSingleVehicle("Regular");
; 会发生什么?你会得到ApplicationException,这就是为什么我们需要通用抽象工厂,如果需要的话我会解释一下。希望它对初学者到中级观众有所帮助。To make it very simple with minimum interface & please focus "//1":
Here important points: 1. Factory & AbstractFactory mechanisms must use inheritance (System.Object-> byte, float ...); so if you have inheritance in program then Factory(Abstract Factory would not be there most probably) is already there by design 2. Creator (MyFactory) knows about concrete type so returns concrete type object to caller(Main); In abstract factory return type would be an Interface.
Important points: 1. Requirement: Honda would create "Regular", "Sports" but Hero would create "DarkHorse", "Sports" and "Scooty". 2. why two interfaces? One for manufacturer type(IVehicleFactory) and another for product factory(IVehicle); other way to understand 2 interfaces is abstract factory is all about creating related objects 2. The catch is the IVehicleFactory's children returning and IVehicle(instead of concrete in factory); so I get parent variable(IVehicle); then I create actual concrete type by calling CreateSingleVehicle and then casting parent object to actual child object. What would happen if I do
RegularBike heroRegularBike = (RegularBike)hero.CreateSingleVehicle("Regular");
; you will get ApplicationException and that's why we need generic abstract factory which I would explain if required. Hope it helps from beginner to intermediate audience.A) 工厂方法模式
工厂方法是一种创建型设计模式,它提供用于创建对象的接口,但允许子类更改将要创建的对象的类型。
如果您在基类和扩展它的子类中有一个创建方法,您可能会查看工厂方法。
B) 抽象工厂模式
抽象工厂是一种创建型设计模式,允许生成相关或依赖对象系列,而无需指定它们的具体类。
什么是“对象族”?例如,采用这组类:Transport + Engine + Controls。这些可能有几种变体:
1- 汽车 + CombustionEngine + SteeringWheel
2- 飞机 + JetEngine + Yoke
如果您的程序不与产品系列一起运行,那么您不需要抽象工厂。
同样,很多人将抽象工厂模式与声明为抽象的简单工厂类混淆了。不要那样做!
参考:https://refactoring.guru/design-patterns/factory-comparison
A) Factory Method pattern
The Factory Method is a creational design pattern that provides an interface for creating objects but allows subclasses to alter the type of an object that will be created.
If you have a creation method in base class and subclasses that extend it, you might be looking at the factory method.
B)Abstract Factory pattern
The Abstract Factory is a creational design pattern that allows producing families of related or dependent objects without specifying their concrete classes.
What are the "families of objects"? For instance, take this set of classes: Transport + Engine + Controls. There are might be several variants of these:
1- Car + CombustionEngine + SteeringWheel
2- Plane + JetEngine + Yoke
If your program doesn’t operate with product families, then you don’t need an abstract factory.
And again, a lot of people mix-up the abstract factory pattern with a simple factory class declared as abstract. Don’t do that!
REF: https://refactoring.guru/design-patterns/factory-comparison
在我看来,@TomDalling 给出的答案确实是正确的(就其价值而言),但是评论中似乎仍然存在很多混乱。
我在这里所做的是创建这两种模式的一些稍微非典型的示例,并试图使它们乍一看非常相似。这将有助于查明区分它们的关键差异。
如果您对这些模式完全陌生,那么这些示例可能不是最好的起点。
工厂方法
Client.javaish
Creator.javaish
为什么会有
Creator
和Client
?为什么不呢?
FactoryMethod
可以与两者一起使用,但将由Creator
的类型决定创建的特定产品。为什么
createProductB
在Creator
中不是抽象的?可以提供默认实现,子类仍然可以重写该方法以提供自己的实现。
我以为工厂方法只能创建一种产品?
每个方法确实只返回一种产品,但创建者可以使用多个工厂方法,它们只是不一定以任何特定方式相关。
抽象工厂
Client.javaish
等等!您的
AbstractFactory
不是,嗯...呃 Abstract没关系,我们仍然提供一个接口。创建方法的返回类型是我们想要制作的产品的超类型。
圣烟蝙蝠侠!
Factory2
不会覆盖createProductA()
,“产品系列”发生了什么?该模式中没有任何内容表明一个对象不能属于多个系列(尽管您的用例可能会禁止它)。每个混凝土工厂负责决定哪些产品可以一起生产。
这是不对的,
Client
没有使用依赖注入,你必须决定你的具体类将在什么地方,
Client
仍然被写入AbstractFactory
接口。这里的困惑在于人们将组合与依赖注入混为一谈。
Client
拥有一个AbstractFactory
,无论它是如何获得的。与 IS-A 关系相反,Client
和AbstractFactory
之间没有继承关系。主要区别
摘要
工厂的目的是向客户端或自身提供对象。
创建者有自己的责任,可能需要使用对象或将它们传递给客户端
仅抽象工厂:
PlantUML 代码(如果您想使用图表):
In my estimation the answer given by @TomDalling is indeed correct (for what it's worth), however there still seems to be a lot of confusion in the comments.
What I've done here is create some slightly atypical examples of the two patterns and tried to make them appear at first glance quite similar. This will help to pinpoint the crtical differences that separate them.
If you're completely new to the patterns these examples are propably not the best place to start.
Factory Method
Client.javaish
Creator.javaish
Why is there a
Creator
and aClient
?Why not? The
FactoryMethod
can be used with both, but it will be the type ofCreator
that determines the specific product created.Why isn't
createProductB
abstract inCreator
?A default implementation can be provided, subclasses can still override the method to provide their own implementation.
I thought factory methods only create one product?
Each method does return just one product, but the creator can use multiple factory methods, they just aren't necessarily related in any particular way.
Abstract Factory
Client.javaish
Wait! Your
AbstractFactory
isn't, well... er AbstractThat's okay, we're still providing an interface. The return types on the create methods are super-types of the products we want to make.
Holy Smoke Batman!
Factory2
doesn't overridecreateProductA()
, what happened to "families of products"?There's nothing in the pattern that says an object can't belong to more than one family (although your use case might prohibit it). Each concrete factory is responsible for deciding which products are allowed to be created together.
That can't be right, the
Client
isn't using dependency injectionYou've got to decide what your concrete classes will be somewhere, the
Client
is still written to theAbstractFactory
interface.The confusion here is that people conflate composition with dependency injection. The
Client
HAS-AAbstractFactory
regardless of how it got it. Contrast with the IS-A relationship,Client
andAbstractFactory
have no inheritance between them.Key Differences
Summary
The purpose of a factory is to provide a objects, either to a client or itself.
A creator has its own responsibilities and may need to use objects or pass them to a client
An abstract factory only:
PlantUML code if you want to play with the diagrams:
任何时候我都更喜欢抽象工厂而不是工厂方法。从上面 Tom Dalling 的示例(顺便说一句,很好的解释)中,我们可以看到抽象工厂更具可组合性,因为我们需要做的就是将不同的工厂传递给构造函数(此处使用构造函数依赖注入)。但工厂方法要求我们引入一个新类(需要管理更多的东西)并使用子类化。总是更喜欢组合而不是继承。
I would favor Abstract Factory over Factory Method anytime. From Tom Dalling's example (great explanation btw) above, we can see that Abstract Factory is more composable in that all we need to do is passing a different Factory to the constructor (constructor dependency injection in use here). But Factory Method requires us to introduce a new class (more things to manage) and use subclassing. Always prefer composition over inheritance.
抽象工厂:工厂的工厂;将各个但相关/依赖的工厂分组在一起的工厂,而不指定它们的具体类。
抽象工厂示例
工厂:它提供了一种将实例化逻辑委托给子类的方法。
工厂模式示例
Abstract Factory: A factory of factories; a factory that groups the individual but related/dependent factories together without specifying their concrete classes.
Abstract Factory Example
Factory: It provides a way to delegate the instantiation logic to child classes.
Factory Pattern Example
请允许我准确地说。大多数答案已经解释过,还提供了图表和示例。
所以我的回答只是一句俏皮话。我自己的话:“抽象工厂模式在多个工厂方法实现上添加了抽象层。这意味着抽象工厂包含或复合一个或多个工厂方法模式”
Allow me to put it precisely. Most of the answers have already explained, provided diagrams and examples as well.
So my answer would just be a one-liner. My own words: “An abstract factory pattern adds on the abstract layer over multiple factory method implementations. It means an abstract factory contains or composite one or more than one factory method pattern”
之前的很多答案都没有提供抽象工厂和工厂方法模式之间的代码比较。下面我尝试通过Java来解释它。我希望它可以帮助需要简单解释的人。
A lot of the previous answers do not provide code comparisons between Abstract Factory and Factory Method pattern. The following is my attempt at explaining it via Java. I hope it helps someone in need of a simple explanation.
我的结论是:没有区别。为什么?因为我看不出有任何理由为工厂以外的对象配备工厂方法 - 否则就会违反责任分离原则。此外,我看不出具有单个工厂方法的工厂和具有多个工厂方法的工厂之间有什么区别:两者都会创建“相关对象的家族”,除非有人可以证明单个家族成员的家族不是一个家族。或者包含单个项目的集合不是集合。
My conclusion: there is no difference. Why? Because I cannot see any justification to equip objects other than factories with factory methods - otherwise you get a violation of the separation of responsibility principle. In addition, I cannot see any difference between a factory with a single factory method and a factory with multiple factory methods: both create "families of related objects" unless anyone can prove that a single-family-member family is not a family. Or a collection that contains a single item is not a collection.