设计模式(二)之Abstract Factory - 抽象工厂模式

来源:互联网 发布:适合程序员的键盘 编辑:程序博客网 时间:2024/05/03 22:31

引用地址:http://www.lifevv.com/sysdesign/doc/20071109154018751.html


Abstract Factory模式的概念

在大规模的系统开发过程中,考虑系统的灵活性,低耦合性,可扩展性等因素,常常不直接使用new来生成类的实例,而是通过一个叫做工厂(Factory)的类来专门生成类的实例。
我们在
设计模式之Factory Method - 工厂方法模式
一文中讨论了Factory Method模式,这里再讨论一下一种更高层次的工厂模式:Abstract Factory模式。

Factory Method模式的主要特点是通过工厂提供的方法生成类的对象,而具体的对象的生成工作被委让给(延迟到)子工厂,所以被称为工厂方法模式。
Abstract Factory模式与Factory Method很相似,都是通过工厂的方法生成目标类的对象,但它们之间的也存在一些区别。

Abstract Factory模式与Factory Method模式的主要区别:

- Factory Method采用的是工厂类继承机制(生成子工厂类,重载该工厂方法,在重载的方法中生成目标对象)。而AbstractFactory强调的是对象组合机制,由在父工厂内定义不同的“子工厂”对象来负责不同的目标对象的创建。再深入一点理解:
-Factory Method模式中,产品(目标对象)的使用者可能需要使用具体的子工厂来生成该产品;AbstractFactory模式则采用传参数的形式直接在父工厂内决定该产品对象应该由哪一个子工厂生产。也就是说,AbstractFactory模式中,跟客户打交道的只有抽象工厂与抽象产品,客户不需要知道产品由哪个工厂生产,也不需要知道被生产的是哪一种具体的产品。
- Factory Method模式中,省城的对象产品只限定于某一类产品;Abstract Factory模式则可以提供多个生产接口生成多类产品
- Abstract Factory模式Factory Method模式的更高层次的抽象,也更最具一般性。可以把Factory Method模式看作是Abstract Factory模式的一种特殊情况

简单一点说,Abstract Factory模式通过抽象工厂为客户(调用者)生成多类产品,抽象工厂负责管理子工厂对象,子工厂负责生成某一类具体的产品对象。

Abstract Factory模式的应用场景:

- 存在多类产品,并需要对这些产品区别对待处理:需要分别为这些产品定义2个以上的接口或抽象类
- 客户端只需要与最上层的工厂(抽象工厂),与最上层的抽象产品打交道

Abstract Factory用到以下几个概念:
- 抽象工厂类(1个):定义创建不同类实例的多个接口;创建与管理子工厂对象,提供统一方法以取得不同的子工厂对象
- 子工厂类(多个):生成具体的类的实例
- 抽象产品类(多个):对产品的抽象
- 具有继承关系的具体的产品类(多个):继承自抽象产品类,它们之间一般存在或多或少的依耐关系

工厂与产品的关系可以用UML类图表示:


下面举例说明。

Abstract Factory模式的实现范例


有一类Bus(公交车)系列产品Bus,ModelBus;
与另一类Truck(卡车)系列产品Truck,ModelTruck;

其中Bus与Truck可以由同一个工厂BusTruckFactory生产;ModelBus与ModelTruck可以由同一个工厂ModelFactory生产。
BusTruckFactory工厂与ModelFactory工厂由总工厂CarFactory统一管理。
我们(客户)直接从CarFactory工厂定购Bus系列产品,与Truck(卡车)系列产品。

下面我们用Abstract Factory模式实现上面的过程

CarFactory:定义生产Bus和Truck的接口规范;管理BusTruckFactory与ModelFactory工厂。
BusTruckFactory:生产Bus和Truck的非模型车。
ModelFactory:生产Bus和Truck的模型车。

AbstractBus:公交车(包括模型与非模型车)父类
Bus:公交车。继承自AbstractBus类。
ModelBus:公交车模型。继承自AbstractBus类。

AbstractTruck:卡车(包括模型与非模型车)父类
Truck:卡车。继承自AbstractTruck类。
ModelTruck:卡车模型。继承自AbstractTruck类。

 

工厂类定义:
总工厂CarFactory.java

view plainprint?
  1. public abstract class CarFactory {  
  2.     public static final int BUS_TRUCK = 1;   //参数定义。生产非模型车。  
  3.     public static final int BUS_TRUCK_MODEL = 2//参数定义。生产模型车。  
  4.       
  5.   
  6.     //定义生产公交车的接口  
  7.     public abstract AbstractBus createBus();  
  8.     //定义生产卡车的接口  
  9.     public abstract AbstractTruck createTruck();  
  10.   
  11.     //管理子工厂类,根据参数调用不同的子工厂进行生产  
  12.     public static CarFactory getCarFactory(int carType) {  
  13.         switch (carType) {  
  14.             case BUS_TRUCK:  
  15.                 return new BusTruckFactory();  
  16.             case BUS_TRUCK_MODEL:  
  17.                 return new ModelFactory();  
  18.             default:  
  19.                 return null;  
  20.         }  
  21.     }  
  22. }  



生产非模型车的工厂BusTruckFactory.java

view plainprint?
  1. public class BusTruckFactory extends CarFactory {  
  2.     //生产公交车(非模型)  
  3.     public AbstractBus createBus() {  
  4.         return new Bus();  
  5.     }  
  6.     //生产卡车(非模型)  
  7.     public AbstractTruck createTruck() {  
  8.         return new Truck();  
  9.     }  
  10. }  



生产模型车的工厂ModelFactory.java

view plainprint?
  1. public class ModelFactory extends CarFactory {  
  2.     //生产公交车模型  
  3.     public AbstractBus createBus() {  
  4.         return new ModelBus();  
  5.     }  
  6.     //生产卡车模型  
  7.     public AbstractTruck createTruck() {  
  8.         return new ModelTruck();  
  9.     }  
  10. }  




产品类定义:
Bus系列产品:

view plainprint?
  1. public class AbstractBus {  
  2.     public String getType() {  
  3.         return "Abstract Bus";  
  4.     }  
  5. }  
  6.   
  7.   
  8. public class Bus extends AbstractBus {  
  9.     public String getType() {  
  10.         return "Bus";  
  11.     }  
  12. }  
  13.   
  14. public class ModelBus extends AbstractBus {  
  15.     public String getType() {  
  16.         return "ModelBus";  
  17.     }  
  18. }  



Truck系列产品:

view plainprint?
  1. public class AbstractTruck {  
  2.     public String getType() {  
  3.         return "Abstract Truck";  
  4.     }  
  5. }  
  6.   
  7.   
  8. public class Truck extends AbstractTruck {  
  9.     public String getType() {  
  10.         return "Truck";  
  11.     }  
  12. }  
  13.   
  14. public class ModelTruck extends AbstractTruck {  
  15.     public String getType() {  
  16.         return "ModelTruck";  
  17.     }  
  18. }  



Client调用:

view plainprint?
  1. public class Client {  
  2.     public static void main(String[] args) {  
  3.     //取得工厂对象  
  4.         CarFactory factory = CarFactory.getCarFactory(CarFactory.BUS_TRUCK);  
  5.         //生产公交车  
  6.         Bus bus = factory.createBus();  
  7.         System.out.println("生产了:" + bus.getType());  
  8.         //生产卡车  
  9.         Truck truck = factory.createTruck();  
  10.         System.out.println("生产了:" + truck.getType());  
  11.   
  12.     //取得工厂对象  
  13.         factory = CarFactory.getCarFactory(CarFactory.BUS_TRUCK_MODEL);  
  14.         //生产公交车  
  15.         bus = factory.createBus();  
  16.         System.out.println("生产了:" + bus.getType());  
  17.         //生产卡车  
  18.         truck = factory.createTruck();  
  19.         System.out.println("生产了:" + truck.getType());  
  20.   }  
  21. }  



执行Client,输出结果:

C:/AbstractFactory>javac *.java
C:/AbstractFactory>java Client
生产了:Bus
生产了:Truck
生产了:ModelBus
生产了:ModelTruck
C:/FactoryMethod>

 

小结

本文比较详细地介绍了Abstract Factory模式的概念,并应用具体的范例让我们更进一步地加深了对Abstract Factory模式的了解。

Abstract Factory模式的应用范围很广,近期我们会使用Abstract Factory模式实现支持多数据库的DAO体系结构。

原创粉丝点击