設計模式筆記11:構建器

Builder


動機

  • 有時候面臨着“一個複雜對象”的創建工作,其通常由各個部分的子對象用一定的算法構成;由於需求的變化,這 個複雜對象的各個部分經常面臨着劇烈的變化,但是將它們組合在一起的算法卻相對穩定
  • 如何應對這種變化?如何提供一種“封裝機制”來隔離出“複雜對象的各個部分”的變化,從而保持系統中的“穩定構建算法”不隨着需求改變而改變?

模式定義

將一個複雜對象的構建其表示相分離,使得同樣的構建過程(穩定)可以創建不同的表示(變化)。 ——《設計模式》GoF


要點總結

  • Builder 模式主要用於“分步驟構建一個複雜的對象”。在這其中**“分步驟”是一個穩定的算法**,而複雜對象的各個部分則經常變化。
  • 變化點在哪裏,封裝哪裏—— Builder模式主要在於應對“複雜對象各個部分”的頻繁需求變動。其缺點在於難以應對“分步驟構建算法”的需求變動。
  • 在Builder模式中,要注意不同語言中構造器內調用虛函數的差別(C++(構造函數中不可以調用虛函數) vs. C#、Java(可以))。

Demo

class House{
    //....
    //1.其中建房子的步驟應寫在一個init函數裏,不能寫在構造函數裏;
    //構造函數調用虛函數是靜態綁定
    //2.如果建房子的步驟太複雜,造成類太肥,則將建房子步驟抽離到HouseDirector類裏
};

class HouseBuilder {
public:
    House* GetResult(){
        return pHouse;
    }
    virtual ~HouseBuilder(){}
protected:
    
    House* pHouse;
	virtual void BuildPart1()=0;
    virtual void BuildPart2()=0;
    virtual void BuildPart3()=0;
    virtual void BuildPart4()=0;
    virtual void BuildPart5()=0;
	
};

class StoneHouse: public House{
    
};

class StoneHouseBuilder: public HouseBuilder{
protected:
    
    virtual void BuildPart1(){
        //pHouse->Part1 = ...;
    }
    virtual void BuildPart2(){
        
    }
    virtual void BuildPart3(){
        
    }
    virtual void BuildPart4(){
        
    }
    virtual void BuildPart5(){
        
    }
    
};


class HouseDirector{
    
public:
    HouseBuilder* pHouseBuilder;
    
    HouseDirector(HouseBuilder* pHouseBuilder){
        this->pHouseBuilder=pHouseBuilder;
    }
    
    House* Construct(){
        
        pHouseBuilder->BuildPart1();
        
        for (int i = 0; i < 4; i++){
            pHouseBuilder->BuildPart2();
        }
        
        bool flag=pHouseBuilder->BuildPart3();
        
        if(flag){
            pHouseBuilder->BuildPart4();
        }
        
        pHouseBuilder->BuildPart5();
        
        return pHouseBuilder->GetResult();
    }
};

注:HouseBuilder與HouseDirector寫在一起也沒什麼問題,主要看類的複雜程度,如果太複雜則抽離抽離抽離…


結構

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章