Sil*_*olt 420 design-patterns factory-method factory-pattern abstract-factory
我知道有很多关于这两种模式之间差异的帖子,但有一些我找不到的东西.
从我一直在阅读的内容中,我看到工厂方法模式允许您定义如何创建单个具体产品,但是从客户端隐藏实现,因为他们将看到通用产品.我的第一个问题是抽象工厂.它的作用是允许您创建具体对象的族(可能取决于您使用的特定工厂)而不仅仅是单个具体对象?抽象工厂是否只返回一个非常大的对象或许多对象,具体取决于您调用的方法?
我的最后两个问题是关于我在很多地方看到过的单一引言,我无法完全理解:
两者之间的一个区别是,使用抽象工厂模式,类通过组合将对象实例化的责任委托给另一个对象,而工厂方法模式使用继承并依赖子类来处理所需的对象实例化.
我的理解是工厂方法模式有一个Creator接口,它将使ConcreteCreator负责知道要实例化的ConcreteProduct.这是通过使用继承来处理对象实例化的意思吗?
现在关于那个引用,抽象工厂模式究竟是如何通过合成将对象实例化的责任委托给另一个对象?这是什么意思?看起来抽象工厂模式也使用继承来完成构建过程,但是我仍然在学习这些模式.
任何帮助,尤其是最后一个问题,将不胜感激.
Tom*_*ing 461
"工厂方法"和"抽象工厂"之间的主要区别在于工厂方法是单个方法,抽象工厂是对象.我想很多人会把这两个术语弄糊涂,并开始互换使用它们.我记得当我学习它们时,我很难找到确切的差异.
因为工厂方法只是一个方法,所以它可以在子类中重写,因此引用的后半部分:
... Factory Method模式使用继承并依赖子类来处理所需的对象实例化.
引用假定对象在此处调用自己的工厂方法.因此,唯一可以改变返回值的是子类.
抽象工厂是一个对象,它有多个工厂方法.看看你的报价的前半部分:
...使用抽象工厂模式,类通过组合将对象实例化的责任委托给另一个对象......
他们所说的是有一个对象A,他想制作一个Foo对象.它不是自己创建Foo对象(例如,使用工厂方法),而是获得一个不同的对象(抽象工厂)来创建Foo对象.
为了向您展示差异,这里是一个使用的工厂方法:
class A {
public void doSomething() {
Foo f = makeFoo();
f.whatever();
}
protected Foo makeFoo() {
return new RegularFoo();
}
}
class B extends A {
protected Foo makeFoo() {
//subclass is overriding the factory method
//to return something different
return new SpecialFoo();
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个使用的抽象工厂:
class A {
private Factory factory;
public A(Factory factory) {
this.factory = factory;
}
public void doSomething() {
//The concrete class of "f" depends on the concrete class
//of the factory passed into the constructor. If you provide a
//different factory, you get a different Foo object.
Foo f = factory.makeFoo();
f.whatever();
}
}
interface Factory {
Foo makeFoo();
Bar makeBar();
Aycufcn makeAmbiguousYetCommonlyUsedFakeClassName();
}
//need to make concrete factories that implement the "Factory" interface here
Run Code Online (Sandbox Code Playgroud)
jga*_*fin 117
抽象工厂使用抽象方法创建基类,这些方法定义应该创建的对象的方法.派生基类的每个工厂类都可以创建自己的每个对象类型的实现.

Factory方法只是用于在类中创建对象的简单方法.它通常添加在聚合根中(Order该类有一个方法调用CreateOrderLine)

在下面的示例中,我们设计了一个接口,以便我们可以将队列创建与消息传递系统分离,从而可以为不同的队列系统创建实现,而无需更改代码库.
interface IMessageQueueFactory
{
IMessageQueue CreateOutboundQueue(string name);
IMessageQueue CreateReplyQueue(string name);
}
public class AzureServiceBusQueueFactory : IMessageQueueFactory
{
IMessageQueue CreateOutboundQueue(string name)
{
//init queue
return new AzureMessageQueue(/*....*/);
}
IMessageQueue CreateReplyQueue(string name)
{
//init response queue
return new AzureResponseMessageQueue(/*....*/);
}
}
public class MsmqFactory : IMessageQueueFactory
{
IMessageQueue CreateOutboundQueue(string name)
{
//init queue
return new MsmqMessageQueue(/*....*/);
}
IMessageQueue CreateReplyQueue(string name)
{
//init response queue
return new MsmqResponseMessageQueue(/*....*/);
}
}
Run Code Online (Sandbox Code Playgroud)
HTTP服务器中的问题是我们总是需要对每个请求进行响应.
public interface IHttpRequest
{
// .. all other methods ..
IHttpResponse CreateResponse(int httpStatusCode);
}
Run Code Online (Sandbox Code Playgroud)
如果没有工厂方法,HTTP服务器用户(即程序员)将被迫使用特定于实现的类,这会破坏IHttpRequest接口的用途.
因此,我们引入工厂方法,以便抽象出响应类的创建.
不同之处在于包含工厂方法的类的预期目的不是创建对象,而抽象工厂只应用于创建对象.
在使用工厂方法时应该注意,因为在创建对象时很容易破坏LSP(Liskov替换原则).
小智 91
AbstractFactory和Factory设计模式之间的区别如下:
工厂方法模式实施: 
AbstractFactory模式实现:

Try*_*ing 24
Abstract Factory是一个用于创建相关产品的界面,但Factory Method只是一种方法.抽象工厂可以通过多种工厂方法实现.

jac*_*646 19
抽象工厂与工厂方法的主要区别在于抽象工厂由Composition实现 ; 但工厂方法由继承实现.
是的,你读得正确:这两种模式之间的主要区别在于旧的构成与继承辩论.
UML图可以在(GoF)书中找到.我想提供代码示例,因为我认为在这个线程中结合前两个答案中的示例将比单独的答案更好地演示.另外,我在课程和方法名称中使用了本书中的术语.
抽象工厂
public class Client {
private final AbstractFactory_MessageQueue factory;
public Client(AbstractFactory_MessageQueue factory) {
// The factory creates message queues either for Azure or MSMQ.
// The client does not know which technology is used.
this.factory = factory;
}
public void sendMessage() {
//The client doesn't know whether the OutboundQueue is Azure or MSMQ.
OutboundQueue out = factory.createProductA();
out.sendMessage("Hello Abstract Factory!");
}
public String receiveMessage() {
//The client doesn't know whether the ReplyQueue is Azure or MSMQ.
ReplyQueue in = factory.createProductB();
return in.receiveMessage();
}
}
public interface AbstractFactory_MessageQueue {
OutboundQueue createProductA();
ReplyQueue createProductB();
}
public class ConcreteFactory_Azure implements AbstractFactory_MessageQueue {
@Override
public OutboundQueue createProductA() {
return new AzureMessageQueue();
}
@Override
public ReplyQueue createProductB() {
return new AzureResponseMessageQueue();
}
}
public class ConcreteFactory_Msmq implements AbstractFactory_MessageQueue {
@Override
public OutboundQueue createProductA() {
return new MsmqMessageQueue();
}
@Override
public ReplyQueue createProductB() {
return new MsmqResponseMessageQueue();
}
}
Run Code Online (Sandbox Code Playgroud)
工厂方法
ConcreteCreator
是客户.换句话说,客户端是其父类定义的子类factoryMethod().这就是为什么我们说Factory Method是通过继承实现的.Creator(父)类调用它自己的factoryMethod().如果我们anOperation()从父类中删除
,只留下一个方法,则它不再是Factory Method模式.换句话说,在父类中使用少于两个方法不能实现Factory Method; 一个人必须援引另一个人.public abstract class Creator {
public void anOperation() {
Product p = factoryMethod();
p.whatever();
}
protected abstract Product factoryMethod();
}
public class ConcreteCreator extends Creator {
@Override
protected Product factoryMethod() {
return new ConcreteProduct();
}
}
Run Code Online (Sandbox Code Playgroud)
杂项.&杂项工厂模式
请注意,尽管GoF定义了两种不同的Factory模式,但这些模式并不是唯一存在的Factory模式.它们甚至不一定是最常用的工厂模式.一个着名的第三个例子是Josh Bloch的Effective Java的静态工厂模式.Head First Design Patterns一书包含了另一种他们称之为Simple Factory的模式.
不要陷入假设每个工厂模式必须与GoF匹配的模式.
Abd*_*nim 11
考虑这个例子以便于理解.
电信公司提供什么?例如,宽带,电话线和移动设备,您被要求创建一个应用程序,以便向其客户提供产品.
通常你在这里做的是,通过你的工厂方法创建产品,即宽带,电话线和移动设备,你知道你对这些产品有什么属性,而且非常简单.
现在,该公司希望为他们的客户提供他们的产品包括宽带,电话线和移动设备,这里有抽象工厂.
换句话说,抽象工厂是负责创建自己的产品的其他工厂的组成,抽象工厂知道如何使这些产品在其自身职责方面更有意义.
在这种情况下,BundleFactory是抽象工厂BroadbandFactory,PhonelineFactory并且MobileFactory是Factory.为了简化更多,这些工厂将采用工厂方法来初始化各个产品.
请看下面的代码示例:
public class BroadbandFactory : IFactory {
public static Broadband CreateStandardInstance() {
// broadband product creation logic goes here
}
}
public class PhonelineFactory : IFactory {
public static Phoneline CreateStandardInstance() {
// phoneline product creation logic goes here
}
}
public class MobileFactory : IFactory {
public static Mobile CreateStandardInstance() {
// mobile product creation logic goes here
}
}
public class BundleFactory : IAbstractFactory {
public static Bundle CreateBundle() {
broadband = BroadbandFactory.CreateStandardInstance();
phoneline = PhonelineFactory.CreateStandardInstance();
mobile = MobileFactory.CreateStandardInstance();
applySomeDiscountOrWhatever(broadband, phoneline, mobile);
}
private static void applySomeDiscountOrWhatever(Broadband bb, Phoneline pl, Mobile m) {
// some logic here
// maybe manange some variables and invoke some other methods/services/etc.
}
}
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助.
现实生活中的例子。(容易记住)
工厂
想象一下,你正在建造一座房子,你向一个木匠找了一扇门。你给出门的尺寸和你的要求,他会为你建造一扇门。在这种情况下,木匠是门的工厂。您的规格是工厂的输入,而门是工厂的输出或产品。
抽象工厂
现在,考虑门的相同示例。你可以去找木匠,也可以去塑料门店或PVC店。都是门厂。根据情况,您决定需要接近什么样的工厂。这就像一个抽象工厂。
我在这里解释了工厂方法模式和抽象工厂模式,首先不使用它们来解释问题,然后使用上述模式解决问题 https://github.com/vikramnagineni/Design-Patterns/tree/master
| 归档时间: |
|
| 查看次数: |
193208 次 |
| 最近记录: |