c++工廠模式(Factory method)


下面以女媧造黑人,白人,黃種人的例子來介紹一下工廠模式。

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:工廠模式在這方面的使用較多。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM