抽象工厂模式与工厂方法的区别

我知道有很多关于这两种模式之间差异的帖子,但是有几件事我找不到。

从我一直在阅读的文章中,我发现工厂方法模式允许您定义如何创建一个具体产品,但隐藏客户端的实现,因为他们会看到一个通用产品。 我的第一个问题是关于抽象工厂。 它的作用是允许你创建具体对象系列(这取决于你使用的具体工厂)而不是仅仅一个具体的对象? 抽象工厂是否只根据您调用的方法返回一个非常大的对象或许多对象?

我最后的两个问题是关于一个单引号,我无法完全理解我在很多地方看到的:

两者之间的一个区别是,使用抽象工厂模式,类将对象实例化的责任委托给另一个对象,而工厂方法模式使用继承并依赖于子类来处理所需的对象实例化。

我的理解是工厂方法模式有一个Creator接口,它将使ConcreteCreator负责知道要实例化哪个ConcreteProduct。 这是通过使用继承来处理对象实例吗?

现在关于这个引用,抽象工厂模式究竟是如何通过合成将对象实例化的责任委托给另一个对象的? 这是什么意思? 看起来抽象工厂模式也使用继承来完成构建过程,但我仍然在学习这些模式。

任何帮助,尤其是最后一个问题,将不胜感激。


二者的区别

“工厂方法”和“抽象工厂”的主要区别在于工厂方法是单一方法,抽象工厂是一个对象。 我认为很多人对这两个术语感到困惑,并开始互换使用它们。 我记得我很难找到当我了解到它们时的差异。

因为工厂方法只是一个方法,所以它可以在子类中被覆盖,因此引用的后半部分:

... Factory Method模式使用继承,并依赖于一个子类来处理所需的对象实例。

该报价假定一个对象在这里调用它自己的工厂方法。 因此唯一可能改变返回值的是一个子类。

抽象工厂是一个拥有多个工厂方法的对象。 看看报价的前半部分:

...通过Abstract Factory模式,类将对象实例化的责任委托给另一个对象,通过组合...

他们说的是有一个对象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();
    }
}

这里有一个正在使用的抽象工厂:

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

抽象工厂创建一个基类,抽象方法为应该创建的对象定义方法。 每个派生基类的工厂类都可以为每个对象类型创建自己的实现。

工厂方法只是用于在类中创建对象的简单方法。 它通常添加在聚合根中( 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(/*....*/);
      }
}

工厂方法

HTTP服务器中的问题是我们总是需要每个请求的响应。

public interface IHttpRequest
{
    // .. all other methods ..

    IHttpResponse CreateResponse(int httpStatusCode);
}

如果没有工厂方法,HTTP服务器用户(即程序员)将被迫使用实现特定的类来IHttpRequest接口的用途。

因此我们引入工厂方法,以便将响应类的创建也抽象出来。

概要

不同之处在于,包含工厂方法的类的预期目的 不是创建对象 ,而抽象工厂只能用于创建对象。

在使用工厂方法时应该小心,因为在创建对象时很容易破坏LSP(Liskovs替换原则)。


AbstractFactory与工厂设计模式的区别如下:

  • Factory Method仅用于创建一个产品,但Abstract Factory则用于创建相关产品或相关产品的族。
  • 工厂方法模式向客户端公开了创建对象的方法,而在抽象工厂的情况下,它们公开了一系列可能由这些工厂方法组成的相关对象。
  • 工厂方法模式隐藏了单个对象的构造,其中抽象工厂方法隐藏了相关对象族的构造。 抽象工厂通常使用(一组)工厂方法来实现。
  • AbstractFactory模式使用合成将创建对象的责任委托给另一个类,而工厂设计模式使用继承并依赖派生类或子类来创建对象。
  • Factory Method模式背后的想法是它允许客户端不知道在运行时需要创建哪些具体类,但只想获得一个可以完成这项工作的类,而AbstractFactory模式是最好的当您的系统需要创建多个产品系列时,或者您希望提供产品库而不暴露实施细节时使用。
  • 工厂方法模式实现: 工厂方法UML

    AbstractFactory模式实现:

    抽象工厂UML

    链接地址: http://www.djcxy.com/p/8827.html

    上一篇: Differences between Abstract Factory Pattern and Factory Method

    下一篇: How do I update the GUI from another thread?