設計模式初學者筆記:Builder模式


      [作者:byeyear    Email:byeyear@hotmail.com    首發:cnblogs    轉載請注明]

      在本文的開頭,先森森的鄙視下自己……將Builder模式反反復復讀了七八遍,才敢說自己對其有了初步的了解。這比花在Abstract Factory上的時間長多了。如果GoF將Builder模式放在第一個講,估計我就會把這本書歸結成天書直接扔一邊了。

      Builder模式的關鍵在於,將“要做什么”與“做出來”分離,將“如何裝配”與“完成裝配”分離:

      Director知道“要做什么”, Builder負責“做出來”;

      Director負責指揮, Builder負責實施;

      Director負責讀懂建築圖紙,Builder負責澆鑄鋼筋水泥;

      Director手里有裝配圖, Builder執行具體的裝配工作。

      說得更加極端一點,只有Director才知道要做出來的是什么東西,但不具體動手;而Builder只負責根據Director的指揮去做事情,但它甚至不知道自己做出來的是什么——雖然最終產品是由Builder交付的。從這個角度來說,將Director翻譯成“指揮官”,builder翻譯成“執行者”似乎更妥帖。

      用GoF的代碼來做例子:

Maze* MazeGame::CreateMaze(MazeBuilder& builder)
{
    // director想要做個新迷宮
    // 他們找了個施工隊builder

    // director說,先做個地基吧
    // builder就做了個地基
    builder.BuildMaze();

    // director又讓builder做了兩個房間
    builder.BuildRoom(1);
    builder.BuildRoom(2);

    // director跟builder說還要在兩個房間之間打個門洞
    builder.BuildDoor(1, 2);

    // director說,把你做的東西交給我吧
    return builder.GetMaze();
}

        過年了,director和builder各自回家。親戚朋友聚會的時候說起這一年都干了些什么——

        director說,我找施工隊造了個迷宮,這個迷宮有兩個房間和一個門(真夠寒酸……);

        builder說,我接了個活,造了兩個房間,還在兩個房間之間打了個洞。天知道這玩意是干嘛用的,那個director准是腦袋秀逗了!

        第二年,director准備繼續造迷宮,而builder繼續在市場上攬活。

        director這次另外找了個施工隊,新的施工隊同樣會干打地基、造房子、打門洞這些活,但新施工隊造的房子是三角形的,而打出的門洞是半圓的:

{
    // 造三角房間和圓門洞的builder
    AnotherMazeBuilder builder;
    // 開工吧,童鞋們!
    CreateMaze((MazeBuilder&)builder);
}

      而原來的builder們有了新的東家,新東家造的迷宮布局不太一樣,不過同樣是由房間和門洞組成:

{
    builder.BuildMaze();
    builder.BuildRoom(0);
    builder.BuildRoom(1);
    builder.BuildRoom(2);
    builder.BuildRoom(0,1);
    builder.BuildRoom(1,2);
    return Builder.GetMaze();
}

      實際上,上面的例子還不是太完善。例如,我們可以將迷宮布局和該迷宮所用房間形狀放在文件里(同一個迷宮使用相同的房間形狀),而director負責解析文件結構並將任務派遣給builder們。這樣,不同的迷宮布局及它們所用房間形狀可以通過更換文件實現,而director不變。如果你需要六邊形的迷宮房間和三角形的門洞,只要重新實現一個新的builder,然后讓director將建造房間、門洞和組裝的任務派遣給這個新的builder。這樣的例子就更接近於GoF書中所用的RTFReader了。

      這里順便引用下《大話設計模式》一書中的相應例子,那個例子中要求小人不能缺胳膊少腿,但從上文中我們可以看出,Builder模式其實是可以造出斷臂維納斯的:

CreateVenus(PersonBuilder& builder)
{
    builder->Prepare();
    builder->BuildHead();
    builder->BuildBody();
    // 斷臂的Venus
    // builder->BuildArmLeft();
    // builder->BuildArmRight();
    builder->BuildLegLeft();
    builder->BuildLegRight();
    return builder->GetPerson();
}

      PersonBuilder類實際上並不知道自己build出來的是不是個完整的Person,只是根據Director的要求造出Head,body,……,並組裝起來。而造出的到底是人棍還是無頭騎士,這個是Director決定的。

      [2014.08.01] 當我們創建對話框的時候,是否可考慮builder模式?Director知道對話框上有哪些子窗口,而Builder負責構建這些子窗口並layout之……


免責聲明!

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



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