建造者模式

在GOF的《設計模式 可復用面向?qū)ο筌浖幕A》中是這樣說的:將一個復雜對象的構建與它的表示分離,使得同樣的構建過程可以創(chuàng)建不同的表示乍恐。

這句話评疗,似懂非懂的。一個復雜對象的創(chuàng)建茵烈,其通常是由很多的子對象構成百匆;如果一個對象能夠直接就創(chuàng)建好了,那么也不會稱之為復雜對象呜投。由于項目中需求的變化加匈,這個復雜對象的各個部分經(jīng)常會發(fā)生劇烈的變化,但是仑荐,不管怎么變化雕拼,將它們組合在一起,組成一個復雜的對象的事實是不會變的粘招。建造者模式就提供了一種“封裝機制”來將各個對象的變化隔離開啥寇,最終,組合成復雜對象的過程是不會變的洒扎。

這也體現(xiàn)了設計模式的一個很重要的思想就是 :封裝不變的部分辑甜,隔離變化的部分。

在《大話設計模式》一書中袍冷,例舉了一個很好的例子————建造小人磷醋。建造一個小人,要分為六步:頭部胡诗、身體邓线、左手、右手煌恢、左腳和右腳骇陈。與抽象工廠模式不同的是,建造者模式是在Director的控制下一步一步的構造出來的症虑,在建造的過程中缩歪,建造者模式可以進行更精細的控制。不管人的頭部谍憔、身體、左手主籍、右手习贫、左腳或者右腳如何變化,但是最終還是由這幾部分組合在一起形成一個人千元,雖然是同一個建造過程苫昌,但是這個人就會有不同的表示,比如幸海,胖子祟身,瘦子奥务,個高的,個低的等等袜硫。

#include <iostream>
using namespace std;

enum ManType
{
    Fatman,
    Thinman,
    Normalman
};

class Man{
private:
    ManType m_type;
public:
    void SetHead(ManType type) { m_type = type; }
    void SetBody(ManType type) { m_type = type; }
    void ShowMan() {
        switch (m_type) {
        case Fatman:
            cout << "fat man" << endl;
            break;
        case Thinman:
            cout << "fat man" << endl;
            break;
        case Normalman:
            cout << "normal man" << endl;
        default:
            return;
        }
        return;
    }
};

class Build {
public:
    virtual void BuildHead(){}
    virtual void BuildBody(){}
    virtual Man * GetMan() { return NULL; }
};

class FatMenBuild :public Build {
private:
    Man * m_FatMan;
public:
    FatMenBuild() {m_FatMan = new Man();}
    void BuildHead(){
        m_FatMan->SetHead(Fatman);
    }

    void BuildBody() {
        m_FatMan->SetBody(Fatman);
    }

    Man * GetMan() { return m_FatMan; }
};

class ThinMenBuild :public Build {
private:
    Man * m_thinMan;
public:
    ThinMenBuild() { m_thinMan = new Man(); }
    void BuildHead() {
        m_thinMan->SetHead(Thinman);
    }
    void BuildBody() {
        m_thinMan->SetBody(Thinman);
    }

    Man * GetMan() { return m_thinMan; }
};

class Director {
public:
    Director(Build * Builder) { m_Builder = Builder; }
    void CreateMan() {
        m_Builder->BuildHead();
        m_Builder->BuildHead();
    }
private:
    Build * m_Builder;
};

int main() {
    //step 1:
    Build * buildobj = new FatMenBuild();
    //step 2:
    Director directorobj(buildobj);
    //step 3:
    directorobj.CreateMan();
    
    //step 4:
    Man * manobj = buildobj->GetMan();
    if (manobj == NULL) {
        return 0;
    }

    manobj->ShowMan();

    delete manobj;
    manobj = NULL;

    delete buildobj;
    buildobj = NULL;


    system("pause");
    return 0;
}
jellythinkBuilderPatternSequence.png

使用要點 :

<ul>
<li>建造者模式生成的對象有復雜的內(nèi)部結構氯葬,將分步驟的去構建一個復雜的對象,分多少步是確定的婉陷,而每一步的實現(xiàn)是不同的帚称,可能經(jīng)常發(fā)生變化;</li>
<li>在上面的例子中秽澳,我們都看到了最終生成的Man和Product都沒有抽象類闯睹,這又導出建造者適用的一種情況,當需要創(chuàng)建復雜對象的過程中担神,復雜對象沒有多少共同的特點楼吃,很難抽象出來時,而復雜對象的組裝又有一定的相似點時妄讯,建造者模式就可以發(fā)揮出作用所刀。簡單的說,可能使用了建造者模式捞挥,最終建造的對象可能沒有多大的關系浮创,關于這一點,閱讀《設計模式 可復用面向?qū)ο筌浖幕A》中的建造者模式時是最有體會的砌函。</li>
</ul>

小結:

一個復雜對象是由多個部件組成的斩披,建造者模式是把復雜對象的創(chuàng)建和部件的創(chuàng)建分別開來,分別用Builder類和Director類來表示讹俊。用Director構建最后的復雜對象垦沉,而在上面Builder接口中封裝的是如何創(chuàng)建一個個部件(復雜對象是由這些部件組成的),也就是說仍劈,Director負責如何將部件最后組裝成產(chǎn)品厕倍。這樣建造者模式就讓設計和實現(xiàn)解耦了。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末贩疙,一起剝皮案震驚了整個濱河市讹弯,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌这溅,老刑警劉巖组民,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異悲靴,居然都是意外死亡臭胜,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來耸三,“玉大人乱陡,你說我怎么就攤上這事∫亲常” “怎么了憨颠?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長睛驳。 經(jīng)常有香客問我烙心,道長,這世上最難降的妖魔是什么乏沸? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任淫茵,我火速辦了婚禮,結果婚禮上蹬跃,老公的妹妹穿的比我還像新娘匙瘪。我一直安慰自己,他們只是感情好蝶缀,可當我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布丹喻。 她就那樣靜靜地躺著,像睡著了一般翁都。 火紅的嫁衣襯著肌膚如雪碍论。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天柄慰,我揣著相機與錄音鳍悠,去河邊找鬼。 笑死坐搔,一個胖子當著我的面吹牛藏研,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播概行,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蠢挡,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了凳忙?” 一聲冷哼從身側響起业踏,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎消略,沒想到半個月后堡称,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡艺演,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片胎撤。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡晓殊,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出伤提,到底是詐尸還是另有隱情巫俺,我是刑警寧澤,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布肿男,位于F島的核電站介汹,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏舶沛。R本人自食惡果不足惜嘹承,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望如庭。 院中可真熱鬧叹卷,春花似錦、人聲如沸坪它。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽往毡。三九已至蒙揣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間开瞭,已是汗流浹背懒震。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留惩阶,地道東北人挎狸。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像断楷,于是被迫代替她去往敵國和親锨匆。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,629評論 2 354

推薦閱讀更多精彩內(nèi)容