C++設(shè)計(jì)模式之抽象工廠模式
問題描述
之前講到了C++設(shè)計(jì)模式——工廠方法模式,我們可能會(huì)想到,后期產(chǎn)品會(huì)越來越多了,建立的工廠也會(huì)越來越多,工廠進(jìn)行了增長(zhǎng),工廠變的凌亂而難于管理;由于工廠方法模式創(chuàng)建的對(duì)象都是繼承于Product的,所以工廠方法模式中,每個(gè)工廠只能創(chuàng)建單一種類的產(chǎn)品,當(dāng)需要生產(chǎn)一種全新的產(chǎn)品(不繼承自Product)時(shí),發(fā)現(xiàn)工廠方法是心有余而力不足。
舉個(gè)例子來說:一個(gè)顯示器電路板廠商,旗下的顯示器電路板種類有非液晶的和液晶的;這個(gè)時(shí)候,廠商建造兩個(gè)工廠,工廠A負(fù)責(zé)生產(chǎn)非液晶顯示器電路板,工廠B負(fù)責(zé)生產(chǎn)液晶顯示器電路板;工廠一直就這樣運(yùn)行著。有一天,總經(jīng)理發(fā)現(xiàn),直接生產(chǎn)顯示器的其余部分也挺掙錢,所以,總經(jīng)理決定,再建立兩個(gè)工廠C和D;C負(fù)責(zé)生產(chǎn)非液晶顯示器的其余部件,D負(fù)責(zé)生產(chǎn)液晶顯示器的其余部件。此時(shí),旁邊參謀的人就說了,經(jīng)理,這樣做不好,我們可以直接在工廠A中添加一條負(fù)責(zé)生產(chǎn)非液晶顯示器的其余部件的生產(chǎn)線,在工廠B中添加一條生產(chǎn)液晶顯示器的其余部件的生產(chǎn)線,這樣就可以不用增加廠房,只用將現(xiàn)有廠房進(jìn)行擴(kuò)大一下,同時(shí)也方便工廠的管理,而且生產(chǎn)非液晶顯示器電路板的技術(shù)人員對(duì)非液晶顯示的其余部件的生產(chǎn)具有指導(dǎo)的作用,生產(chǎn)液晶顯示器電路板也是同理。總經(jīng)理發(fā)現(xiàn)這是一個(gè)不錯(cuò)的主意。
再回到軟件開發(fā)的過程中來,工廠A和B就是之前所說的C++設(shè)計(jì)模式——工廠方法模式;總經(jīng)理再次建立工廠C和D,就是重復(fù)C++設(shè)計(jì)模式——工廠方法模式,只是生產(chǎn)的產(chǎn)品不同罷了。這樣做的弊端就如參謀所說的那樣,增加了管理成本和人力成本。在面向?qū)ο箝_發(fā)的過程中,是很注重對(duì)象管理和維護(hù)的,對(duì)象越多,就越難進(jìn)行管理和維護(hù);如果工廠數(shù)量過多,那么管理和維護(hù)的成本將大大增加;雖然生產(chǎn)的是不同的產(chǎn)品,但是可以二者之間是有微妙的關(guān)系的,如參謀所說,技術(shù)人員的一些技術(shù)經(jīng)驗(yàn)是可以借鑒的,這就相當(dāng)于同一個(gè)類中的不同對(duì)象,之間是可以公用某些資源的。那么,增加一條流水線,擴(kuò)大廠房,當(dāng)然是最好的主意了。
實(shí)際問題已經(jīng)得到了解決,那么如何使用設(shè)計(jì)模式模擬這個(gè)實(shí)際的問題呢?那就是接下來所說的抽象工廠模式。
UML類圖
現(xiàn)在要講的抽象工廠模式,就是工廠方法模式的擴(kuò)展和延伸,但是抽象工廠模式,更有一般性和代表性;它具有工廠方法具有的優(yōu)點(diǎn),也增加了解決實(shí)際問題的能力。

如圖所示,抽象工廠模式,就好比是兩個(gè)工廠方法模式的疊加。抽象工廠創(chuàng)建的是一系列相關(guān)的對(duì)象,其中創(chuàng)建的實(shí)現(xiàn)其實(shí)就是采用的工廠方法模式。在工廠Factory中的每一個(gè)方法,就好比是一條生產(chǎn)線,而生產(chǎn)線實(shí)際需要生產(chǎn)什么樣的產(chǎn)品,這是由Factory1和Factory2去決定的,這樣便延遲了具體子類的實(shí)例化;同時(shí)集中化了生產(chǎn)線的管理,節(jié)省了資源的浪費(fèi)。
適用場(chǎng)合
工廠方法模式適用于產(chǎn)品種類結(jié)構(gòu)單一的場(chǎng)合,為一類產(chǎn)品提供創(chuàng)建的接口;而抽象工廠方法適用于產(chǎn)品種類結(jié)構(gòu)多的場(chǎng)合,主要用于創(chuàng)建一組(有多個(gè)種類)相關(guān)的產(chǎn)品,為它們提供創(chuàng)建的接口;就是當(dāng)具有多個(gè)抽象角色時(shí),抽象工廠便可以派上用場(chǎng)。
代碼實(shí)現(xiàn)
/*
** FileName : AbstractFactoryPatternDemo
** Author : Jelly Young
** Date : 2013/11/19
** Description : More information
*/
#include <iostream>
using namespace std;
// Product A
class ProductA
{
public:
virtual void Show() = 0;
};
class ProductA1 : public ProductA
{
public:
void Show()
{
cout<<"I'm ProductA1"<<endl;
}
};
class ProductA2 : public ProductA
{
public:
void Show()
{
cout<<"I'm ProductA2"<<endl;
}
};
// Product B
class ProductB
{
public:
virtual void Show() = 0;
};
class ProductB1 : public ProductB
{
public:
void Show()
{
cout<<"I'm ProductB1"<<endl;
}
};
class ProductB2 : public ProductB
{
public:
void Show()
{
cout<<"I'm ProductB2"<<endl;
}
};
// Factory
class Factory
{
public:
virtual ProductA *CreateProductA() = 0;
virtual ProductB *CreateProductB() = 0;
};
class Factory1 : public Factory
{
public:
ProductA *CreateProductA()
{
return new ProductA1();
}
ProductB *CreateProductB()
{
return new ProductB1();
}
};
class Factory2 : public Factory
{
ProductA *CreateProductA()
{
return new ProductA2();
}
ProductB *CreateProductB()
{
return new ProductB2();
}
};
int main(int argc, char *argv[])
{
Factory *factoryObj1 = new Factory1();
ProductA *productObjA1 = factoryObj1->CreateProductA();
ProductB *productObjB1 = factoryObj1->CreateProductB();
productObjA1->Show();
productObjB1->Show();
Factory *factoryObj2 = new Factory2();
ProductA *productObjA2 = factoryObj2->CreateProductA();
ProductB *productObjB2 = factoryObj2->CreateProductB();
productObjA2->Show();
productObjB2->Show();
if (factoryObj1 != NULL)
{
delete factoryObj1;
factoryObj1 = NULL;
}
if (productObjA1 != NULL)
{
delete productObjA1;
productObjA1= NULL;
}
if (productObjB1 != NULL)
{
delete productObjB1;
productObjB1 = NULL;
}
if (factoryObj2 != NULL)
{
delete factoryObj2;
factoryObj2 = NULL;
}
if (productObjA2 != NULL)
{
delete productObjA2;
productObjA2 = NULL;
}
if (productObjB2 != NULL)
{
delete productObjB2;
productObjB2 = NULL;
}
}
相關(guān)文章
C++實(shí)現(xiàn) vector 的四則運(yùn)算
本文給大家介紹的是在C++中實(shí)現(xiàn)高效的vector四則運(yùn)算的方法的相關(guān)資料,需要的朋友可以參考下2016-07-07
實(shí)現(xiàn)一個(gè)random?shuffle算法示例
這篇文章主要為大家介紹了實(shí)現(xiàn)一個(gè)random?shuffle算法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05
C++默認(rèn)參數(shù)與函數(shù)重載及注意事項(xiàng)
這篇文章主要介紹了C++默認(rèn)參數(shù)與函數(shù)重載及注意事項(xiàng)包括語(yǔ)法與使用,通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2020-03-03
基于MFC實(shí)現(xiàn)自定義復(fù)選框效果
復(fù)選框是一種可同時(shí)選中多項(xiàng)的基礎(chǔ)控件,主要是有兩種明顯的狀態(tài):選中與非選中。本文將通過MFC框架實(shí)現(xiàn)自定義復(fù)選框效果,感興趣的可以了解一下2022-02-02
C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)鏈表隊(duì)列的實(shí)現(xiàn)
這篇文章主要介紹了C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)鏈表隊(duì)列的實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下2017-07-07
Windows10配置VSCode C++環(huán)境(超詳細(xì),面向小白以及大佬們)
這篇文章主要介紹了Windows10配置VSCode C++環(huán)境(超詳細(xì),面向小白以及大佬們),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12
C++類與對(duì)象深入之運(yùn)算符重載與const及初始化列表詳解
運(yùn)算符是程序中最最常見的操作,例如對(duì)于內(nèi)置類型的賦值我們直接使用=賦值即可,因?yàn)檫@些編譯器已經(jīng)幫我們做好了,但是對(duì)象的賦值呢?能直接賦值嗎2022-06-06

