Abstract Factory(抽象工厂)模式

Abstract Factory (抽象工厂)模式

 

GoF Abstract Factory 模 式的意图是“提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类”。

 

工厂模式有 : 抽象 工厂 (Abstract Factory) 、工厂方法 (Factory Method) 。依照《设计模式精解》的顺序,这里先学习 Abstract Factory 模式。

 

工厂模式是传说中用的最广的模式了。我们通常用某个类 Class 来生成一个对象,例如: A a = new A();  所谓工厂就是生产某种产品的地方。那么工厂模式就是用来生成一些列产品(对象)的。有时候,几个对 象需要按照相同的样式被实例化。比如说,在处理显示器显示精度的时候,有些机器能显示高清晰图像,而有些机器只能显示低分辨率图像。那么在工作上就要求系 统去适配最合适的功能。 Abstract Factory 模式能确保系统总能根据当前的情况获得合 适的对象。

 

假如我们要开发一个系统,要求提供打印驱动和显示驱动,还要求在不同 配置的机器上要有合适的驱动,例如:在高配置的机器上要求精度高的驱动,在低配置的机器上要求精度低的驱动。

 

开始的解决方法这样:提供一个 DisplayDriver 抽象类(或者接口)然后派生出两个类 Lrdd (提 供低精度显示驱动)和 Hrdd (提供高精度显示驱动);再提供一个 PrintDriver 抽象类(或者接口)然后派生出两个类 Lrpd (提 供低精度打印驱动) Hrpd (提供高精度打印驱动)。最后在 ApControl 类中分别实例化四个派生类的对象来提供相关的驱动。这样做是很合理的,但是当需求改变了,现在要求提供中等精度的驱动,或者其它要求。我们又 从那两个抽象类中分别派生出若干子类。这样又出现了类爆炸的情况,我们要在 ApControl 类中分别实例化那些类才能提供我们所要的功能。这时我们就应该想一下用 Abstract Factory 模式了。先看一下 Abstract Factory 模式的 UML 图:

( )

Abstract Factory 模式 UML

在上图中我们可以看到,用一个工厂( ResFractory )来“生产”我们需要的“产品”(类)。我们不管有多少具体类,在 Abstract Factory 模式中 ApControl 类只使用 Abstract Factory 类( ResFactory 类)和 Abstract Product 类( DisplayDriver 类和 PrintDriver 类)的接口。通常在运行时刻创建一个具体类的实例。这一具体的工厂创建具有特定实现的产品对象。为 创建不同的产品对象,客户应使用不同的具体工厂。 Abstract Factory 将产品对 象的创建延迟到它的具体子类中。

 

下面给出上图 的简易代码:

先创建产品:

package Factory;

 

public abstract class DisplayDriver

{

       public abstract void dDriver();// 抽 象方法,使派生类能够自由实现所需的显示功能。

      

}//end abstract class DisplayDriver

 

 

package Factory;

 

public class Lrdd extends DisplayDriver

{

 

       public Lrdd()

       {

              System.out.println(" 低分辨率 __ 显示 驱动 ");

       }//end Lrdd()

      

       public void dDriver() // 实现基类抽象方法

       {

              System.out.println(" 显示出 __ 低分辨率图像 ");

       }//end dDrover()

      

}//end class Lrdd

 

 

package Factory;

 

public class Hrdd extends DisplayDriver

{

       public Hrdd()

       {

              System.out.println(" 高分辨率 -- 显示 驱动 ");

       }//end Hrdd()

 

       public void dDriver()

       {

              System.out.println(" 显示出 -- 高分辨率图像 ");

       }//end dDriver()

 

}//end class Hrdd

 

 

package Factory;

 

public abstract class PrintDriver

{

       public abstract void pDriver();// 抽 象方法,使派生类能够自由实现所需的打印功能。

      

}//end abstract class PrintDriver

 

 

package Factory;

 

public class Lrpd extends PrintDriver

{

 

       public Lrpd()

       {

              System.out.println(" 低分辨率 __ 打印 驱动 ");

       }//end Lrpd()

 

       public void pDriver()

       {

              System.out.println(" 打印 __ 低分辨率图像 ");

       }//end pDriver()

      

}//end class Lrpd

 

 

package Factory;

 

public class Hrpd extends PrintDriver

{

 

       public Hrpd()

       {

              System.out.println(" 高分辨率 -- 打印 驱动 ");

       }//end Hrpd()

 

       public void pDriver()

       {

              System.out.println(" 打印 -- 高分辨率图像 ");

       }//end pDriver()

 

}//end class Hrpd

 

再创建工厂:

package Factory;

 

public abstract class ResFactory

{

       // 抽象方法,使派生类自由实现显示功能

       abstract public DisplayDriver getDispDrvr();

      

       // 抽象方法,使派生类自由实现打印功能

       abstract public PrintDriver getPrtDrvr();

}//end abstract class ResFactory

 

 

package Factory;

 

public class LowResFact extends ResFactory {

 

       public LowResFact()

       {

              System.out.println(" 低分辨率 ----> 驱动 ");

       }//end LowResFact()

 

       public DisplayDriver getDispDrvr()

       {

              return new Lrdd();

       }//end getDispDrvr()

 

       public PrintDriver getPrtDrvr()

       {

              return new Lrpd();

       }//end getPrtDrvr()

 

}//end class LowResFact

 

 

package Factory;

 

public class HighResFact extends ResFactory

{

 

       public HighResFact()

       {

              System.out.println(" 高分辨率 ----> 驱动 ");

       }//end HighResFact()

 

       public DisplayDriver getDispDrvr()

       {

              return new Hrdd();

       }//end getDispDrvr()

 

       public PrintDriver getPrtDrvr()

       {

              return new Hrpd();

       }//end getPrtDrvr()

 

}//end class HighResFact

 

 

利用工厂产生不同的产品:

package Factory;

 

public class ApControl

{

       private DisplayDriver lowDisplayDriver; // 需要 -- -- 分辨率 -- 显示 -- 驱动

       private PrintDriver highPrintDriver; // 需要 -- -- 分辨率 -- 打印 -- 驱动

      

       //     生产出低分 辨率驱动(注:没有说明是低显示驱动还是低打印驱动)

       private ResFactory lowDriver;

      

       //     生产出高分 辨率驱动(注:没有说明是高显示驱动还是高打印驱动)

       private ResFactory highDriver;

 

       public ApControl()

       {

              lowDriver = new LowResFact();// 实例化低分 辨率驱动对象

              highDriver = new HighResFact();// 实例化高 分辨率驱动对象

       }//end ApControl()

 

       public void displayDriver()

       {

              lowDisplayDriver = lowDriver.getDispDrvr();// 得到低分辨率驱动

              lowDisplayDriver.dDriver();// 低分辨率显示驱动

             

              highPrintDriver = highDriver.getPrtDrvr();// 得到低分辨率驱动

              highPrintDriver.pDriver();// 高分辨率显示驱动

       }//end displayDriver()

      

       public static void main(String[] args)

       {

              System.out.println("Abstract Factory");

              ApControl ac = new ApControl();

              ac.displayDriver();

       }//end main(...)

 

}//end class ApControl

 

输出结果如下:

Abstract Factory

低分辨率 ----> 驱动

高分辨率 ----> 驱动

低分辨率 __ 显示驱动

显示出 __ 低分辨率图像

高分辨率 -- 打印驱动

打印 -- 高分辨率图像

 

Abstract Factory 模式适用性:

l         在以下情况可以使用 Abstract Factory 模式:

l         一个系统 要独立于他的产品的创建、组合和表示时;

l         一个系统 要由多个产品系列中的一个来配置时;

l         当你要强 调一系列相关的产品对象的设计以便进行联合使用时;

l         当你提供 一个产品类库,而只想显示他们的接口而不是实现时。

 

Abstract Factory 模式中 ApControl 的责 任是知道如何与合适的对象协同工作; ResFactory 的责 任是提供合适的对象。

 

Abstract Factory 模式:关键特征

l          意图:你需要为 特定的客户(或情况)提供特定系列的对象。

l          问题:一系列相 关的对象需要被实例化。

l          解决方案:协调 不同系列对象的创建过程。提供一种方法保持“如何在客户对象外部执行兑现实例化”的规则,客户对象将使用这些实例化出来的对象。

l          参与者 与协作者: Abstract Factory 为 “如何创建需要的每一个系列的对象”定义接口。典型的情况下,每个系列都独立拥有自己的 ConcreteFactory ,通过它被实例化。

l          效果:这个模式 将“使用哪些对象”的规则与“如何使用这些对象”的逻辑相隔离。

l          实现: 定义一个抽象类来指定那些对象将被创建。然后为每个系列实现一个具体类。表或文件也可以被用于达到同样的目的

 

下面是 Abstract Factory 模式涉及的 3 关键策略:

1 . 发现 并封装变化点

       “使用哪个驱动对象”的选择食变化的。所以,将它封装在 ResFactory 类中。

2 . 优先 使用对象组合,而不是类继承

       将变化点放在一个独立的对象—— ResFactory 对象——中并让 ApControl 对象使用 ResFactory 对象,而不是拥有两类不同的 ApControl 对象。

3 . 针对 接口设计,而不是针对实现设计

       ApControl 知道 怎样想 ResFactory 请求实 例化驱动对象——它不知道(或不关心) ResFactory 对象 实际如何响应这一请求。

你可能感兴趣的:(设计模式)