C++设计模式之二 AbstractFactory模式

设计模式的目的就是尽量减少“变化”对程序的影响,尤其是对客户程序的影响。AbstractFactory模式作为创建型模式的一种,解决的就是“new”在变化中可能引起的问题。

先来看看new有何种不好,举个创建汽车的车门的例子:
很自然的一种想法是:Door *door = new Door();
但是如果遇到创建老爷车的车门,创建现代车的车门,这段代码就无所适从了。

OO为我们提供了哪些精华的思想?“封装”,是的,将车门的创建封装起来,于是我们有了静态工厂方法: 
客户程序代码:

1 Door *  door  =  doorFactory -> CreateDoor();

库程序代码:

1 class  DoorFactory
2 {
3public:
4  Door* CreateDoor()
5  {
6    return new Door();
7  }

8}

客户程序在此是不会变化的,不管你是老爷车门,现代车门,还是钻石车门,这些和客户程序代码都是没关系的,究竟CreateDoor出来如何结果都交给多态来判断,我们不用操心。
但是库程序代码还是需要更改的,但我们已经将“变化”与客户程序隔离了。


需求又有变化了,不光要创建车门,还需要创建引擎,车灯,而且还是不同风格的。
这时候静态工厂已经应付不来了,静态工厂有其自身的缺陷“不能应对不同系列对象”的变化。

动机:
软件系统中,经常面临“一系列相互依赖的对象”的创建工作。(两个特征:“一系列”,“相互依赖”)
将创建过程封装起来,避免“客户程序”和“多系列具体对象的创建工作”的紧耦合。

意图:
提供一个接口,让该接口负责创建一系列“相关或者相互依赖的对象”,无需指定他们具体的类。(GoF23)

思路:
C++设计模式之二 AbstractFactory模式_第1张图片

对于客户程序来说,只依赖于三个抽象的类:AbstractFactory,AbstractProductA,AbstractProductB。
以下是客户程序代码:

 1 class  CarManager
 2 {
 3protected:
 4    AbstractFactory *abstractFactory;
 5public:
 6    //创造Car
 7    void createCar(AbstractFactory *abstractFactory)
 8    {
 9        abstractFactory->CreateEngine();
10        abstractFactory->CreateDoor();
11        abstractFactory->CreateLight();
12    }

13    //其他的操作
14    void run(){}
15}
;
16
17 int  _tmain( int  argc, _TCHAR *  argv[])
18 {
19    CarManager *carManager = new CarManager();
20    //创建Classic风格的汽车
21    carManager->createCar(new ClassicFactory());
22
23    return 0;
24}

所有关于创建的操作都是用抽象类完成的,对于具体是何种类型的对象由多态实现,以此来使“客户代码”和“多系列具体对象的创建工作”达到松耦合。

如果遇到还需要扩展其他风格的汽车,可以按下图的思路
C++设计模式之二 AbstractFactory模式_第2张图片
红色的部分对应新风格的车辆,只需在库程序中添加ConcreteFactory3,ProductA3,ProductB3三个类,而对于客户代码CarManager来说完全不受影响。

总结:
AbstractFactory模式有以下三个要点:
1.应对的问题是“多风格的系列对象创建”的变化问题,“系列对象”指的是这些对象之间有相互依赖或者相互作用的关系。否则使用“静态工厂”足以。
2.抽象工厂和静态工厂的核心是“封装”,将对象的创建进行封装,避免“new”引起的问题
3.抽象工程的另一个核心是“多态”,通过动态绑定来处理“不同风格”的问题

注:
AbstractFactory模式主要针对“风格”的变化,如果“对象”本身经常变化,那么该模式并不适用。


自己做的示例代码,仅供参考

  1 //////////////////////////////////////////////////////////////////////////
  2 //  AbstractFactoryTest for AbstractFactory Pattern Test
  3 //
  4 //////////////////////////////////////////////////////////////////////////
  5
  6 #include  " stdafx.h "
  7 #include  " iostream "
  8 using   namespace  std;
  9
 10 // Engine,Door,Light are the Abstract Product
 11 // 这三个类对应UML图中的AbstractProduct类
 12 class  Engine
 13 {
 14public:
 15    Engine()
 16    {
 17        cout<<"Abstract Engine Create"<<endl;
 18    }

 19    virtual void doSomething() = 0;
 20}
;
 21
 22 class  Door
 23 {
 24public:
 25    Door()
 26    {
 27        cout<<"Abstract Door Create"<<endl;
 28    }

 29    virtual void doSomething() = 0;
 30}
;
 31
 32 class  Light
 33 {
 34public:
 35    Light()
 36    {
 37        cout<<"Abstract Light Create"<<endl;
 38    }

 39    virtual void doSomething() = 0;
 40}
;
 41
 42 // Abstract Factory
 43 class  AbstractFactory
 44 {
 45public:
 46    AbstractFactory()
 47    {
 48        cout<<"AbstractFactory Create"<<endl;
 49    }

 50    virtual Engine* CreateEngine() = 0;
 51    virtual Door* CreateDoor() = 0;
 52    virtual Light* CreateLight() = 0;
 53}
;
 54
 55 // SpeedEngine,SpeedDoor,SpeedLight are the Products of Speed Style 
 56 // 这三个类对应UML图中的ProductA1,ProductB1,ProductC1类
 57 class  SpeedEngine: public  Engine
 58 {
 59public :
 60    SpeedEngine()
 61    {
 62        cout<<"Speed Engine Create"<<endl;
 63    }

 64    void doSomething(){    }
 65}
;
 66
 67 class  SpeedDoor: public  Door
 68 {
 69public :
 70    SpeedDoor()
 71    {
 72        cout<<"Speed Door Create"<<endl;
 73    }

 74    void doSomething(){    }
 75}
;
 76
 77 class  SpeedLight: public  Light
 78 {
 79public :
 80    SpeedLight()
 81    {
 82        cout<<"Speed Light Create"<<endl;
 83    }

 84    void doSomething(){    }
 85}
;
 86
 87 // classicEngine,classicDoor,classicLight are the products of Classic style
 88 // 这三个类对应UML图中的ProductA2,ProductB2,ProductC2类
 89 class  ClassicEngine: public  Engine
 90 {
 91public :
 92    ClassicEngine()
 93    {
 94        cout<<"Classic Engine Create"<<endl;
 95    }

 96    void doSomething(){    }
 97}
;
 98
 99 class  ClassicDoor: public  Door
100 {
101public :
102    ClassicDoor()
103    {
104        cout<<"Classic Door Create"<<endl;
105    }

106    void doSomething(){    }
107}
;
108
109 class  ClassicLight: public  Light
110 {
111public :
112    ClassicLight()
113    {
114        cout<<"Classic Light Create"<<endl;
115    }

116    void doSomething(){    }
117}
;
118
119 // Factory for Speed Cars
120 // 对应UML图中的ConcreteFactory1类
121 class  SpeedFactory: public  AbstractFactory
122 {
123public:
124    SpeedFactory()
125    {
126        cout<<"SpeedFactory Create"<<endl;
127    }

128    virtual Engine* CreateEngine()
129    {
130        return new SpeedEngine();
131    }

132    virtual Door* CreateDoor() 
133    {
134        return new SpeedDoor();
135    }

136    virtual Light* CreateLight()
137    {
138        return new SpeedLight();
139    }

140}
;
141
142 // Factory for classic Cars
143 // 对应UML图中的ConcreteFactory2类
144 class  ClassicFactory: public  AbstractFactory
145 {
146public:
147    ClassicFactory()
148    {
149        cout<<"ClassicFactory Create"<<endl;
150    }

151    virtual Engine* CreateEngine()
152    {
153        return new ClassicEngine();
154    }

155    virtual Door* CreateDoor() 
156    {
157        return new ClassicDoor();
158    }

159    virtual Light* CreateLight()
160    {
161        return new ClassicLight();
162    }

163}
;
164
165 // Client Code ---- use the Abstract Factory & Abstract Product to create the car
166 // this is never changed
167 class  CarManager
168 {
169protected:
170    AbstractFactory *abstractFactory;
171public:
172    //创造Car
173    void createCar(AbstractFactory *abstractFactory)
174    {
175        abstractFactory->CreateEngine();
176        abstractFactory->CreateDoor();
177        abstractFactory->CreateLight();
178    }

179    //其他的操作
180    void run(){}
181}
;
182
183 int  _tmain( int  argc, _TCHAR *  argv[])
184 {
185    CarManager *carManager = new CarManager();
186    //创建Classic风格的汽车
187    carManager->createCar(new ClassicFactory());
188
189    return 0;
190}

你可能感兴趣的:(C++设计模式之二 AbstractFactory模式)