C++设计模式之二 AbstractFactory模式
設計模式的目的就是盡量減少“變化”對程序的影響,尤其是對客戶程序的影響。AbstractFactory模式作為創建型模式的一種,解決的就是“new”在變化中可能引起的問題。
先來看看new有何種不好,舉個創建汽車的車門的例子:
很自然的一種想法是:Door *door = new Door();
但是如果遇到創建老爺車的車門,創建現代車的車門,這段代碼就無所適從了。
OO為我們提供了哪些精華的思想?“封裝”,是的,將車門的創建封裝起來,于是我們有了靜態工廠方法:?
客戶程序代碼:
庫程序代碼:
1class?DoorFactory2{
3public:
4??Door*?CreateDoor()
5??{
6????return?new?Door();
7??}
8}
客戶程序在此是不會變化的,不管你是老爺車門,現代車門,還是鉆石車門,這些和客戶程序代碼都是沒關系的,究竟CreateDoor出來如何結果都交給多態來判斷,我們不用操心。
但是庫程序代碼還是需要更改的,但我們已經將“變化”與客戶程序隔離了。
需求又有變化了,不光要創建車門,還需要創建引擎,車燈,而且還是不同風格的。
這時候靜態工廠已經應付不來了,靜態工廠有其自身的缺陷“不能應對不同系列對象”的變化。
動機:
軟件系統中,經常面臨“一系列相互依賴的對象”的創建工作。(兩個特征:“一系列”,“相互依賴”)
將創建過程封裝起來,避免“客戶程序”和“多系列具體對象的創建工作”的緊耦合。
意圖:
提供一個接口,讓該接口負責創建一系列“相關或者相互依賴的對象”,無需指定他們具體的類。(GoF23)
思路:
對于客戶程序來說,只依賴于三個抽象的類:AbstractFactory,AbstractProductA,AbstractProductB。
以下是客戶程序代碼:
?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
17int?_tmain(int?argc,?_TCHAR*?argv[])
18{
19????CarManager?*carManager?=?new?CarManager();
20????//創建Classic風格的汽車
21????carManager->createCar(new?ClassicFactory());
22
23????return?0;
24}
所有關于創建的操作都是用抽象類完成的,對于具體是何種類型的對象由多態實現,以此來使“客戶代碼”和“多系列具體對象的創建工作”達到松耦合。
如果遇到還需要擴展其他風格的汽車,可以按下圖的思路
紅色的部分對應新風格的車輛,只需在庫程序中添加ConcreteFactory3,ProductA3,ProductB3三個類,而對于客戶代碼CarManager來說完全不受影響。
總結:
AbstractFactory模式有以下三個要點:
1.應對的問題是“多風格的系列對象創建”的變化問題,“系列對象”指的是這些對象之間有相互依賴或者相互作用的關系。否則使用“靜態工廠”足以。
2.抽象工廠和靜態工廠的核心是“封裝”,將對象的創建進行封裝,避免“new”引起的問題
3.抽象工程的另一個核心是“多態”,通過動態綁定來處理“不同風格”的問題
注:
AbstractFactory模式主要針對“風格”的變化,如果“對象”本身經常變化,那么該模式并不適用。
自己做的示例代碼,僅供參考
??2//?AbstractFactoryTest?for?AbstractFactory?Pattern?Test
??3//
??4//
??5
??6#include?"stdafx.h"
??7#include?"iostream"
??8using?namespace?std;
??9
?10//Engine,Door,Light?are?the?Abstract?Product
?11//這三個類對應UML圖中的AbstractProduct類
?12class?Engine
?13{
?14public:
?15????Engine()
?16????{
?17????????cout<<"Abstract?Engine?Create"<<endl;
?18????}
?19????virtual?void?doSomething()?=?0;
?20};
?21
?22class?Door
?23{
?24public:
?25????Door()
?26????{
?27????????cout<<"Abstract?Door?Create"<<endl;
?28????}
?29????virtual?void?doSomething()?=?0;
?30};
?31
?32class?Light
?33{
?34public:
?35????Light()
?36????{
?37????????cout<<"Abstract?Light?Create"<<endl;
?38????}
?39????virtual?void?doSomething()?=?0;
?40};
?41
?42//Abstract?Factory
?43class?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類
?57class?SpeedEngine:public?Engine
?58{
?59public?:
?60????SpeedEngine()
?61????{
?62????????cout<<"Speed?Engine?Create"<<endl;
?63????}
?64????void?doSomething(){????}
?65};
?66
?67class?SpeedDoor:public?Door
?68{
?69public?:
?70????SpeedDoor()
?71????{
?72????????cout<<"Speed?Door?Create"<<endl;
?73????}
?74????void?doSomething(){????}
?75};
?76
?77class?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類
?89class?ClassicEngine:public?Engine
?90{
?91public?:
?92????ClassicEngine()
?93????{
?94????????cout<<"Classic?Engine?Create"<<endl;
?95????}
?96????void?doSomething(){????}
?97};
?98
?99class?ClassicDoor:public?Door
100{
101public?:
102????ClassicDoor()
103????{
104????????cout<<"Classic?Door?Create"<<endl;
105????}
106????void?doSomething(){????}
107};
108
109class?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類
121class?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類
144class?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
167class?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
183int?_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模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 蔚来发布便携式充放电一体机:只租不卖 1
- 下一篇: 7700万家禽遭捕杀!传播了26年的禽流