阿Sam的设计模式学习笔记----抽象工厂(Abstract Factory)模式

上回讲了 Simple Factory Factory Method 。简单回顾一下:
  • Simple Factory :定义一个类(工厂)负责创建其他类(产品)的实例,产品实例通常具有共同的父类。
  • Factory Method :将工厂抽象一把,在父类中提供一个标准接口,由各个子类(具体工厂)决定创建什么样的实例(具体产品)。
Factory Method 只能生产“一维”层次的,横向产品。也就是说,工厂生产的东东都是一类产品,都是由同一个父类派生的子类的对象。比如上次举例说到的,不管是 Nokia 的还是 Motorola 的,生产的都是手机,产品都是从 Mobile 派生出来的。
如果要想纵向的生产产品,比如,生产一个基站(这个东西好像大了点,但是偶实在想不出更好的产品了), Factory Method 恐怕就不够用了。
各位看官请注意了,下面隆重介绍 Abstract Factory
1,  功能:
《设计模式》中的定义是“提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类”。所谓一系列,就说明他们不都是一个父类派生出来的,但是这些对象是为了以后的应用,或者整体应用所提供的。他们之间多少有些相关或者相互依赖。
2,  基本思想:
Factory Method 可以理解为同一种产品的不同具体产品的工厂的抽象。每个具体的工厂生产出来的东东都是同一种产品(同一个父类)。
Abstract Factory 是对不用种产品(但存在一定联系)的具体产品的工厂的抽象。每个具体工厂生产出来的东东不是同一种产品(不同的父类),但有一定联系(比如同一个厂家的产品,或者同一个窗口的组件)。
3,  适用情况:
一个系统要独立于它的产品的创建、组合和表示时;
一个系统要有多个产品系列中的一个来配置时;
需要强调一系列相关的产品对象的设计以便进行联合使用时;
当要提供一个产品类库,而只想显示它们的接口而不是实现时。
4,  案例举例:
实现在不同窗口系统之间的可移动性,比如 Windows 操作系统中抽象工厂创建 Windows 下的窗口组件, Linux 创建 Linux 的窗口组件,等等。
5,  结构:
6 ,代码示例:还是用 Nokia Moto 两大通信公司的 case 来说明一下:
A. Nokia Moto 两个公司都生产手机
class  MobilePhone
{
public :
    virtual 
void  call() {cout  <<   " Calling "   <<  endl; }  //  打电话
    virtual  void  shortMsg() {cout  <<   " Short Message "   <<  endl;};  // 收发短信
};
class  NokiaPhone :  public  MobilePhone
{
    virtual 
void  call() { cout << " Nokia calling " << endl; }
    virtual 
void  shortMsg() { cout  <<   " Nokia short message "   <<  endl; }
};
class  MotoPhone :  public  MobilePhone
{
    virtual 
void  call() { cout  <<   " Moto calling " << endl; }
    virtual 
void  shortMsg() { cout  <<   " Moto short message "   <<  endl; }
};
B Nokia Moto 两个公司都生产基站系统
class  BaseStation
{
public :
    virtual 
void  BTSControl() {cout  <<   " Controlling BTS "   <<  endl;}
    virtual 
void  BSCControl() {cout  <<   " Controlling BSC "   <<  endl;}
};
class  NokiaBaseStation :  public  BaseStation
{
public :
    
void  BTSControl() {cout  <<   " Nokia BTS control "   <<  endl;}
    
void  BSCControl() {cout  <<   " Nokia BSC control "   <<  endl;}
};
class  MotoBaseStation :  public  BaseStation
{
public :
    
void  BTSControl() {cout  <<   " Moto BTS control "   <<  endl;}
    
void  BSCControl() {cout  <<   " Moto BSC control "   <<  endl;}
};
C.抽象的工厂提供了标准的、生产所有不同种类产品(手机、基站)的接口。不同系列的产品由该系列的工厂生产。 Nokia 的手机和基站系统由 Nokia 的工厂生产, Motorola 的手机和基站系统由 Motorola 公司生产。
 
class  Factory
{
public :
    virtual MobilePhone 
*  CreatePhone()  =  NULL;
    virtual 
void  DestroyPhone(MobilePhone  *  p) { if (p) delete p;};
    virtual BaseStation 
*  CreateBaseStation()  =  NULL;
    virtual 
void  DestroyBaseStation(BaseStation  *  b) { if  (b) delete b;};
};
class  NokiaFactory :  public  Factory
{
public :
    MobilePhone 
*  CreatePhone() {  return  ( new  NokiaPhone());}
    BaseStation 
*  CreateBaseStation() { return  ( new  NokiaBaseStation());}
};
class  MotoFactory :  public  Factory
{
    MobilePhone 
*  CreatePhone() {  return  ( new  MotoPhone());}
    BaseStation 
*  CreateBaseStation() { return  ( new  MotoBaseStation());}
};
D .下面客户端利用 Factory 创建不同系列的工厂对象,再利用这些工厂对象来创建对应系列的产品。
int  main()
{
    Factory 
* nokiaFac  =   new  NokiaFactory();
    Factory 
* motoFac  =   new  MotoFactory();
    MobilePhone 
*  nokia  =  nokiaFac -> CreatePhone();
    MobilePhone 
*  moto  =  motoFac -> CreatePhone();
   
    nokia
-> call();
    nokia
-> shortMsg();
    moto
-> call();
    moto
-> shortMsg();
 
    BaseStation 
*  nokiaBS  =  nokiaFac -> CreateBaseStation();
    BaseStation 
*  motoBS  =  motoFac -> CreateBaseStation();
 
    nokiaBS
-> BSCControl();
    nokiaBS
-> BTSControl();
    motoBS
-> BSCControl();
    motoBS
-> BTSControl();
 
    nokiaFac
-> DestroyBaseStation(nokiaBS);
    nokiaFac
-> DestroyPhone(nokia);
    motoFac
-> DestroyBaseStation(motoBS);
    motoFac
-> DestroyPhone(moto);
 
    
return   0 ;
}
 
    上面的例子,用图来表示如下图:
7 ,总结
(1)       抽象工厂分离了客户和类的实现,客户通过工厂的抽象接口来得到产品的实例,客户不知道产品是如何生成的,具体产品类的名称也不会出现在客户代码中。
(2)       Abstract Factory 中,一个具体的工厂类在一个应用中仅出现一次(在初始化的时候),只需改变具体的工厂即可生产出一系列具有相关性的产品。
(3)       Abstract Factory Factory Method 最大的区别就是: Factory Method 针对同一级的产品,这些产品往往拥有共同的父类; Abstract Factory 对应的是多个产品级的结构。所以在涉及到 Abstract Factory 的时候常常提到“产品族”的概念。产品族是指位于不同产品等级结构中,并且功能相互关联的产品系列,比如基站系统和手机属于不同级别的产品,但是他们是联合工作的。
(4)       Abstract Factory 也有不足之处。尤其是扩展新的产品系列, Abstract Factory 的影响会非常大。比如我们要想新添加 Alcatel 产品系列, Alcatel 又要生产 MSC (移动交换中心)这个产品,此时不仅仅 Abstract Factory 需要修改以支持新产品,每个具体工厂类也必须修改(需要添加 MSC 产品的生产接口,尽管可能 Nokia 或者 Moto 不生产 MSC )。这时,如果在 Abstract Factory 中的为生产 MSC 的接口提供缺省实现,可以避免修改已有具体工厂类(前题:这些具体工厂不负责生产新的产品)。
(5)       通常, Abstract Factory 在整个应用中只有一个实例,所以可以结合 Singleton 模式。

你可能感兴趣的:(设计模式,Class,手机,Nokia,Motorola,产品)