建造模式(Builder)

定義

建造模式是對象的創(chuàng)建模式粟关。建造模式可以將一個產(chǎn)品的內(nèi)部表象(internal representation)與產(chǎn)品的生產(chǎn)過程分割開來涡扼,從而可以使一個建造過程生成具有不同的內(nèi)部表象的產(chǎn)品對象奋渔〉ぶ澹—閻宏《JAVA與模式》

一個產(chǎn)品常有不同的組成成分作為產(chǎn)品的零件,這些零件有可能是對象节榜,也有可能不是對象狼忱,它們通常又叫做產(chǎn)品的內(nèi)部表象(internal representation)膨疏。不同的產(chǎn)品可以有不同的內(nèi)部表象,也就是不同的零件钻弄。使用建造模式可以使客戶端不需要知道所生成的產(chǎn)品有哪些零件佃却,每個產(chǎn)品的對應零件彼此有何不同,是怎么建造出來的窘俺,以及怎么組成產(chǎn)品饲帅。


構造模式的結(jié)構

1、抽象建造者(Builder)角色:給 出一個抽象接口瘤泪,以規(guī)范產(chǎn)品對象的各個組成成分的建造灶泵。一般而言,此接口獨立于應用程序的商業(yè)邏輯对途。模式中直接創(chuàng)建產(chǎn)品對象的是具體建造者 (ConcreteBuilder)角色赦邻。具體建造者類必須實現(xiàn)這個接口所要求的兩種方法:一種是建造方法(buildPart1和 buildPart2),另一種是返還結(jié)構方法(retrieveResult)实檀。一般來說惶洲,產(chǎn)品所包含的零件數(shù)目與建造方法的數(shù)目相符按声。換言之,有多少 零件湃鹊,就有多少相應的建造方法儒喊。

2镣奋、具體建造者(ConcreteBuilder)角色:擔任這個角色的是與應用程序緊密相關的一些類币呵,它們在應用程序調(diào)用下創(chuàng)建產(chǎn)品的實例。這個角色要完成的任務包括:1.實現(xiàn)抽象建造者Builder所聲明的接口侨颈,給出一步一步地完成創(chuàng)建產(chǎn)品實例的操作余赢。2.在建造過程完成后,提供產(chǎn)品的實例哈垢。

3妻柒、導演者(Director)角色:擔任這個角色的類調(diào)用具體建造者角色以創(chuàng)建產(chǎn)品對象。應當指出的是耘分,導演者角色并沒有產(chǎn)品類的具體知識举塔,真正擁有產(chǎn)品類的具體知識的是具體建造者角色。

4求泰、產(chǎn)品(Product)角色:產(chǎn)品便是建造中的復雜對象央渣。一般來說,一個系統(tǒng)中會有多于一個的產(chǎn)品類渴频,而且這些產(chǎn)品類并不一定有共同的接口芽丹,而完全可以是不相關聯(lián)的。

UML圖

構造模式UML圖.png

代碼
產(chǎn)品類Product

public class Product {
    /**
     * 定義一些關于產(chǎn)品的操作
     */
    private String part1;
    private String part2;
    public String getPart1() {
        return part1;
    }
    public void setPart1(String part1) {
        this.part1 = part1;
    }
    public String getPart2() {
        return part2;
    }
    public void setPart2(String part2) {
        this.part2 = part2;
    }
}

抽象建造者類Builder

public interface Builder {
    public void buildPart1();
    public void buildPart2();
    public Product retrieveResult();
}

具體建造者類ConcreteBuilder

public class ConcreteBuilder implements Builder {

    private Product product = new Product();
    /**
     * 產(chǎn)品零件建造方法1
     */
    @Override
    public void buildPart1() {
        //構建產(chǎn)品的第一個零件
     product.setPart1("編號:9527");
    }
    /**
     * 產(chǎn)品零件建造方法2
     */
    @Override
    public void buildPart2() {
        //構建產(chǎn)品的第二個零件
     product.setPart2("名稱:XXX");
    }
    /**
     * 產(chǎn)品返還方法
     */
    @Override
    public Product retrieveResult() {
        return product;
    }
}

導演者類Director

public class Director {
    /**
     * 持有當前需要使用的建造器對象
     */
    private Builder builder;
    /**
     * 構造方法卜朗,傳入建造器對象
     * @param builder 建造器對象
     */
    public Director(Builder builder){
        this.builder = builder;
    }
    /**
     * 產(chǎn)品構造方法拔第,負責調(diào)用各個零件建造方法
     */
    public void construct(){
        builder.buildPart1();
        builder.buildPart2();
    }
}

客戶端類Client

public class Client {
    public static void main(String[]args){
        Builder builder = new ConcreteBuilder();
        Director director = new Director(builder);
        director.construct();
        Product product = builder.retrieveResult();
        System.out.println(product.getPart1());
        System.out.println(product.getPart2());
    }
}

使用場景及說明

不管如何變化,建造模式都存在這么兩個部分场钉,一個部分是部件構造和產(chǎn)品裝配蚊俺,另一個部分是整體構建的算法。認識這點是很重要的逛万,因為在建造模式中春叫,強調(diào)的是固定整體構建的算法,而靈活擴展和切換部件的具體構造和產(chǎn)品裝配的方式泣港。

有時候暂殖,Builder接口沒有必要定義,直接提供一個具體的建造者類就可以了当纱。

對于創(chuàng)建一個復雜的對象呛每,可能會有很多種不同的選擇和步驟,干脆去掉“導演者”坡氯,把導演者的功能和Client的功能合并起來晨横,也就是說,Client這個時候就相當于導演者洋腮,它來指導構建器類去構建需要的復雜對象。

在什么時候使用建造模型
1手形、需要生成的產(chǎn)品對象有復雜的內(nèi)部結(jié)構啥供,每一個內(nèi)部成分本身可以是對象,也可以僅僅是一個對象(即產(chǎn)品對象)的一個組成部分库糠。
2伙狐、需要生成的產(chǎn)品對象的屬性相互依賴。建造模式可以強制實行一種分步驟進行的建造過程瞬欧,因此贷屎,如果產(chǎn)品對象的一個屬性必須在另一個屬性被3、在對象創(chuàng)建過程中會使用到系統(tǒng)中的其他一些對象艘虎,這些對象在產(chǎn)品對象的創(chuàng)建過程中不易得到唉侄。

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市野建,隨后出現(xiàn)的幾起案子属划,更是在濱河造成了極大的恐慌,老刑警劉巖候生,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件同眯,死亡現(xiàn)場離奇詭異,居然都是意外死亡陶舞,警方通過查閱死者的電腦和手機嗽测,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來肿孵,“玉大人唠粥,你說我怎么就攤上這事⊥W觯” “怎么了晤愧?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蛉腌。 經(jīng)常有香客問我官份,道長,這世上最難降的妖魔是什么烙丛? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任舅巷,我火速辦了婚禮,結(jié)果婚禮上河咽,老公的妹妹穿的比我還像新娘钠右。我一直安慰自己,他們只是感情好忘蟹,可當我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布飒房。 她就那樣靜靜地躺著搁凸,像睡著了一般。 火紅的嫁衣襯著肌膚如雪狠毯。 梳的紋絲不亂的頭發(fā)上护糖,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天,我揣著相機與錄音嚼松,去河邊找鬼嫡良。 笑死,一個胖子當著我的面吹牛惜颇,可吹牛的內(nèi)容都是我干的皆刺。 我是一名探鬼主播少辣,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼凌摄,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了漓帅?” 一聲冷哼從身側(cè)響起锨亏,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎忙干,沒想到半個月后器予,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡捐迫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年乾翔,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片施戴。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡反浓,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出赞哗,到底是詐尸還是另有隱情雷则,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布肪笋,位于F島的核電站月劈,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏藤乙。R本人自食惡果不足惜猜揪,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望坛梁。 院中可真熱鬧而姐,春花似錦、人聲如沸罚勾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至丈莺,卻和暖如春划煮,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背缔俄。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工弛秋, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人俐载。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓蟹略,卻偏偏與公主長得像,于是被迫代替她去往敵國和親遏佣。 傳聞我的和親對象是個殘疾皇子挖炬,可洞房花燭夜當晚...
    茶點故事閱讀 45,033評論 2 355

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