抽象工厂(Abstract Factory)

摘自:http://www.vincehuston.org/dp/abstract_factory.html

翻译如下,有错之处请指出

定义:

1.抽象工厂只提供了一个创建产品族的接口,而不需要直接指明已实现的类。

产品族:每一个族中的产品必须具有相互关联或依赖的关系(这样才能对这些产品定义一个公共接口,相应具有了多态性).  抽象工厂包含许多族(能产生相应产品的接口或方法)。然后在派生出具体工厂,生产出产品。

2.通过继承,蕴涵了许多可能的平台"platforms", 和构造一套产品"products"的接口。

3.New 操作可能带来坏处。如果在客户端直接产生产品,这样就增加了耦合性,对将来的维护带来很大的影响。他的核心就是客户类与工厂类的分离。产品的实现封装在工厂里,通过多态性可以产生不同的产品。

产生的问题:

如果一个应用程序要通用的话,那么它就要封装平台的倚赖性.这些平台"platforms" 可能包括:windowing system, operating system, database, etc.  而且,很多时候,封装并没有被事先考虑到,只是用#ifdef case 来判断,

结构图:

 1.定义一套要创建的产品,对应不同的平台。(定义接口或类)

 2.通过继承接口,实现针对不同平台的方法。

3.创建一个抽象工厂,把平台的性质用继承层级塑造出来(也就是说,继承不同抽象产品),通过在基类中声明creareProductX/createProductY等方法。每一个方法在派生的具体工厂中通过“New"来构造产品。

4.不同的平台,包裹了一套分类的产品。

我们来讨论一下,它只是间接的提供一个抽象的创建方法,而不用指明具体的要创建的类。工厂对象提供了什么服务呢?就是创建所有平台的产品族.客户并不需要直接创建,只是向工厂索要就可以了.这种机制使得在众多产品族间转换更为方便,因为在程序中工厂对象只需初始化一次.

通过构造不同的抽象对象的具体实例,应用程序就能够简单的取代所有的产品族.

通常抽象工厂的使用很普遍,所以经常作为单例模式来应用.

抽象工厂为每一个产品定义了工厂方法,每一个方法都概括了New和实现具体的、特定平台的产品类。

每一个平台 "platform"都是抽象工厂的继承类。

 

//  AFTER - The client: creates a platform-
//  specific "factory" object, is careful
//  to eschew use of "new", and delegates
//  all creation requests to the factory.

#define  WINDOWS

class  Widget  {            //抽象产品类
public:
   
virtual void draw() = 0;
}
;

class  MotifButton :  public  Widget  {         //具体产品
public:
   
void draw() { cout << "MotifButton "; }
}
;
class  MotifMenu :  public  Widget  {         //具体产品
public:
   
void draw() { cout << "MotifMenu "; }
}
;

class  WindowsButton :  public  Widget  {      //具体产品
public:
   
void draw() { cout << "WindowsButton "; }
}
;
class  WindowsMenu :  public  Widget  {       //具体产品
public:
   
void draw() { cout << "WindowsMenu "; }
}
;

class  Factory  {            //抽象工厂
public:
   
virtual Widget* create_button() = 0;   //创建产品抽象方法,具有多态性
   
virtual Widget* create_menu() = 0;    //创建产品抽象方法,具有多态性
}
;

class  MotifFactory :  public  Factory  {     //具体工厂
public:
   Widget
* create_button() {    
      
return new MotifButton; }               //具体创建产品

   Widget
* create_menu()   {
      
return new MotifMenu; }            //具体创建产品

}
;

class  WindowsFactory :  public  Factory  {       //具体工厂
public:
   Widget
* create_button() {       
      
return new WindowsButton; }          //具体创建产品

   Widget
* create_menu()   {
      
return new WindowsMenu; }    //具体创建产品

}
;

Factory
*  factory;

void  display_window_one()  {       
   Widget
* w[] = { factory->create_button(),
                   factory
->create_menu() }
;
   w[
0]->draw();  w[1]->draw();
}


void  display_window_two()  {
   Widget
* w[] = { factory->create_menu(),
                   factory
->create_button() }
;
   w[
0]->draw();  w[1]->draw();
}


int  main(  void  )  {
#ifdef MOTIF
   factory 
= new MotifFactory;      //动态构造工厂
#else // WINDOWS
   factory 
= new WindowsFactory;
#endif

   Widget
* w = factory->create_button();
   w
->draw();
   display_window_one();
   display_window_two();
}


//  WindowsButton
//  WindowsButton
//  WindowsMenu
//  WindowsMenu
//  WindowsButton

1。在创建模式时,并不局限于一种模式,抽象工厂可能有一套原形模式,能够克隆并返回对象。Builder 可以使用其他模式,来执行那些组建应当被构造。

2。Abstract Factory, Builder, and Prototype 定义一个工厂对象,他们负责应如何理解和创建(knowing and creating)这些产品类对象,并使其成为一个系统的参数。抽象工厂包含创建对象的几个类。Building 由工厂对象建立一个复杂的产品,并逐步采用相应复杂的议定书。Prototype由工厂对象 通过克隆Prototype 对象来创建产品。

3。Abstract Factory通常由工厂方法来执行,但有时也用Prototype来执行。

4。Abstract Factory可以作为一种替代,以幌子的形式来隐藏平台的具体类。

5。Building 侧重于逐步构建一个复杂的对象,Abstract Factory 强调产品对象族(无论简单还是复杂)。Building返回最后的产品(最后一步创建),但就抽象工厂而言,该产品立刻返回。

6。很多时候,设计开始用工厂方法(不复杂的、易定制的和能增加自类的)逐渐向抽象工厂、原型或Building(更灵活,更复杂)演化,作为设计师,应具有发现那里应当有更大的灵活性的眼光。

终于看完了,一头雾水,继续研究,E文不好,有错的地方,请大家告诉我。

小结以下:

抽象工厂包含4部分:

1.抽象工厂角色:只提供产生产品的方法。

2.具体工厂角色:实现抽象工厂接口具体的类,与应用类密切相关,产生最终产品。

3.抽象产品角色:所要创建产品的超类,具有共同的接口。

4.具体产品角色:实现产品的类,与客护端密切相关。

返回类型为抽象类型,保证了产品的多态性。当增加产品时,只需增加第2和4即可,支持”开--闭“原则。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值