下面以女媧造黑人,白人,黃種人的例子來介紹一下工廠模式。
1.工廠的接口,相當於造人工廠總部。
class IHumanFactory { public: IHumanFactory(void) { } ~IHumanFactory(void) { } virtual IHuman* CreateHuman() = 0; };
2.造人各個的部門
class WhiteHumanFactory: public IHumanFactory { public: WhiteHumanFactory(void) { } ~WhiteHumanFactory(void) { } IHuman *CreateHuman() { return new WhiteHuman(); } }; class YellowHumanFactory: public IHumanFactory { public: YellowHumanFactory(void) { } ~YellowHumanFactory(void) { } IHuman *CreateHuman() { return new YellowHuman(); } }; class BlackHumanFactory: public IHumanFactory { public: BlackHumanFactory(void) { } ~BlackHumanFactory(void) { } IHuman *CreateHuman() { return new BlackHuman(); } };
3.各種人的特征。
class IHuman { public: IHuman(void) { } ~IHuman() { } virtual void Laugh() = 0; virtual void Cry() = 0; virtual void Talk() = 0; }; class WhiteHuman : public IHuman { public: WhiteHuman(void) { } ~WhiteHuman(void) { } void Laugh() { std::cout << "白種人笑!" << std::endl; } void Cry() { std::cout << "白種人哭!" <<std::endl; } void Talk() { std::cout << "白種人說話!" <<std::endl; } }; class YellowHuman : public IHuman { public: YellowHuman(void) { } ~YellowHuman(void) { } void Laugh() { std::cout << "黃種人笑!" << std::endl; } void Cry() { std::cout << "黃種人哭!" <<std::endl; } void Talk() { std::cout << "黃種人說話!" <<std::endl; } }; class BlackHuman : public IHuman { public: BlackHuman(void) { } ~BlackHuman(void) { } void Laugh() { std::cout << "黑種人笑!" << std::endl; } void Cry() { std::cout << "黑種人哭!" <<std::endl; } void Talk() { std::cout << "黑種人說話!" <<std::endl; } };
4.主函數
int main() { std::cout << "#1.制造黃種人"<<std::endl; IHumanFactory *pHumanFactory = new YellowHumanFactory(); IHuman * pHuman = pHumanFactory->CreateHuman(); pHuman->Cry(); pHuman->Laugh(); pHuman->Talk(); delete pHuman; delete pHumanFactory; std::cout << "#1.制造白種人"<<std::endl; IHumanFactory *pHumanFactory2 = new WhiteHumanFactory(); IHuman * pHuman2 = pHumanFactory->CreateHuman(); pHuman->Cry(); pHuman->Laugh(); pHuman->Talk(); delete pHuman2; delete pHumanFactory2; std::cout << "#1.制造黑種人"<<std::endl; IHumanFactory *pHumanFactory3 = new BlackHumanFactory(); IHuman * pHuman3 = pHumanFactory->CreateHuman(); pHuman->Cry(); pHuman->Laugh(); pHuman->Talk(); delete pHuman3; delete pHumanFactory3; getchar(); return 0; }
輸出結果:
#1.制造黃種人 黃種人哭! 黃種人笑! 黃種人說話! #1.制造白種人 白種人哭! 白種人笑! 白種人說話! #1.制造黑種人 黑種人哭! 黑種人笑! 黑種人說話!
工廠模式的好處:
工廠模式就相當於創建實例對象的new,我們經常要根據類Class生成實例對象,如A a=new A(). 工廠模式也是用來創建實例對象的,可能多做一些工作,但會給你系統帶來更大的可擴展性和盡量少的修改量。
類Sample為例,要創建Sample的實例對象:
Sample sample=new Sample();
可是,實際情況是,通常我們都要在創建sample實例時做點初始化的工作,比如賦值 查詢數據庫等
首先,我們想到的是,可以使用Sample的構造函數,這樣生成實例就寫成:
Sample sample=new Sample(參數);
但是,如果創建sample實例時所做的初始化工作不是象賦值這樣簡單的事,可能是很長一段代碼,如果也寫入構造函數中,那你的代碼很難看了
初 始化工作如果是很長一段代碼,說明要做的工作很多,將很多工作裝入一個方法中,相當於將很多雞蛋放在一個籃子里,是很危險的,這也是有背於Java面向對 象的原則,面向對象的封裝(Encapsulation)和分派(Delegation)告訴我們,盡量將長的代碼分派“切割”成每段,將每段再“封裝” 起來(減少段和段之間偶合聯系性),這樣,就會將風險分散,以后如果需要修改,只要更改每段,不會再發生牽一動百的事情。
我們需要將創建實例的工作與使用實例的工作分開, 也就是說,讓創建實例所需要的大量初始化工作從Sample的構造函數中分離出去。
你想如果有多個類似的類,我們就需要實例化出來多個類。這樣代碼管理起來就太復雜了。
這個時候你就可以采用工廠方法來封裝這個問題。
不能再用上面簡單new Sample(參數)。還有,如果Sample有個繼承如MySample, 按照面向接口編程,我們需要將Sample抽象成一個接口.現在Sample是接口,有兩個子類MySample 和HisSample
Sample mysample=new MySample();
Sample hissample=new HisSample();
采用工廠封裝:
public class Factory{
public static Sample creator(int which){
//getClass 產生Sample 一般可使用動態類裝載裝入類。
if (which==1)
return new SampleA();
else if (which==2)
return new SampleB();
}
}
那么在你的程序中,如果要實例化Sample時.就使用
Sample sampleA=Factory.creator(1);
舉 個更實際的例子,比如你寫了個應用,里面用到了數據庫的封裝,你的應用可以今后需要在不同的數據庫環境下運行,可能是oracle,db2,sql server等,那么連接數據庫的代碼是不一樣的,你用傳統的方法,就不得不進行代碼修改來適應不同的環境,非常麻煩,但是如果你采用工廠類的話,將各種 可能的數據庫連接全部實現在工廠類里面,通過你配置文件的修改來達到連接的是不同的數據庫,那么你今后做遷移的時候代碼就不用進行修改了。
我通常都是用xml的配置文件配置許多類型的數據庫連接,非常的方便。PS:工廠模式在這方面的使用較多。