3固翰、創(chuàng)建型模式之建造者模式

建造者模式

建造者模式(Builder Pattern)使用多個簡單的對象一步一步構建成一個復雜的對象收厨。這種類型的設計模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對象的最佳方式砸讳。

一個 Builder 類會一步一步構造最終的對象琢融。該 Builder 類是獨立于其他對象的。

介紹

意圖:將一個復雜的構建與其表示相分離簿寂,使得同樣的構建過程可以創(chuàng)建不同的表示漾抬。

主要解決:主要解決在軟件系統(tǒng)中,有時候面臨著"一個復雜對象"的創(chuàng)建工作常遂,其通常由各個部分的子對象用一定的算法構成纳令;由于需求的變化,這個復雜對象的各個部分經(jīng)常面臨著劇烈的變化烈钞,但是將它們組合在一起的算法卻相對穩(wěn)定泊碑。

何時使用:一些基本部件不會變,而其組合經(jīng)常變化的時候毯欣。

如何解決:將變與不變分離開馒过。

關鍵代碼:建造者:創(chuàng)建和提供實例,導演:管理建造出來的實例的依賴關系酗钞。

應用實例: 1腹忽、去肯德基,漢堡砚作、可樂窘奏、薯條、炸雞翅等是不變的葫录,而其組合是經(jīng)常變化的着裹,生成出所謂的"套餐"。 2米同、JAVA 中的 StringBuilder骇扇。

優(yōu)點: 1摔竿、建造者獨立,易擴展少孝。 2继低、便于控制細節(jié)風險。

缺點: 1稍走、產(chǎn)品必須有共同點袁翁,范圍有限制绿贞。 2获列、如內(nèi)部變化復雜,會有很多的建造類溯警。

建造者模式包括的角色:
(1)Builder:給出一個抽象接口或抽象類盖淡,以規(guī)范產(chǎn)品的建造年柠。這個接口規(guī)定要實現(xiàn)復雜對象的哪些部分的創(chuàng)建,并不涉及具體的對象部件的創(chuàng)建褪迟,一般由子類具體實現(xiàn)。
(2)ConcreteBuilder:Builder接口的實現(xiàn)類答憔,并返回組建好對象實例味赃。
(3)Director:調(diào)用具體建造者來創(chuàng)建復雜對象的各個部分,在指導者中不涉及具體產(chǎn)品的信息虐拓,只負責保證對象各部分完整創(chuàng)建或按某種順序創(chuàng)建心俗。
(4)Product:要創(chuàng)建的復雜對象,產(chǎn)品類蓉驹。

建造者模式的使用場景:
(1)當產(chǎn)品有復雜的內(nèi)部構造時(參數(shù)很多)城榛。
(2)需要生產(chǎn)的產(chǎn)品的屬性相互依賴,這些屬性的賦值順序比較重要時(因為在調(diào)用ConcreteBuilder的賦值方法時是有先后順序的)态兴。

注意事項:與工廠模式的區(qū)別是:建造者模式更加關注與零件裝配的順序狠持。

案例一

下面是利用建造者模式“組裝一臺電腦”的實現(xiàn)方式,便于理解該模式如何運用瞻润。
1.產(chǎn)品類
要組裝一臺電腦(Computer類)喘垂,我們假設它有三個部件:CPU 、主板以及內(nèi)存绍撞。
在Computer類中提供三個set方法分別設置這三個屬性正勒。

public class Computer {  
    private String mCpu;  
    private String mMainboard;  
    private String mRam;  
  
    public void setmCpu(String mCpu) {  
        this.mCpu = mCpu;  
    }  
  
    public void setmMainboard(String mMainboard) {  
        this.mMainboard = mMainboard;  
    }  
  
    public void setmRam(String mRam) {  
        this.mRam = mRam;  
    }  
}  

2 .Builder類
下面就是一個抽象的Builder類,里面提供了安裝CPU傻铣、主板和內(nèi)存的抽象方法章贞,以及組裝成電腦的create方法。

public abstract class Builder {  
    public abstract void buildCpu(String cpu);  
    public abstract void buildMainboard(String mainboard);  
    public abstract void buildRam(String ram);  
    public abstract Computer create();  
}  

3. Builder實現(xiàn)類
下面是一個繼承Builder的子類非洲,里面不僅新建了Computer的實例鸭限,還提供了安裝CPU就谜、主板和內(nèi)存的具體實現(xiàn)方法,并且在組裝成電腦的create方法中將該Computer對象實例返回里覆。

public class MyComputerBuilder extends Builder {  
    private Computer mComputer = new Computer();  
    @Override  
    public void buildCpu(String cpu) {  
        mComputer.setmCpu(cpu);  
    }  
  
    @Override  
    public void buildMainboard(String mainboard) {  
        mComputer.setmMainboard(mainboard);  
    }  
  
    @Override  
    public void buildRam(String ram) {  
        mComputer.setmRam(ram);  
    }  
  
    @Override  
    public Computer create() {  
        return mComputer;  
    }  
}  

4 .Director類
指揮者(Director)類用來規(guī)范組裝電腦的流程順序丧荐,先安裝主板,再安裝CPU喧枷,最后安裝內(nèi)存并組裝成電腦虹统。

public class Direcror {  
    Builder mBuild=null;  
    public Direcror(Builder build){  
        this.mBuild=build;  
    }  
    public Computer CreateComputer(String cpu,String mainboard,String ram){  
        //規(guī)范建造流程,這個順序是由它定的  
       this.mBuild.buildMainboard(mainboard);  
       this.mBuild.buildCpu(cpu);  
       this.mBuild.buildRam(ram);  
       return mBuild.create();  
    }  
}  

5.使用

Builder mBuilder = new MyComputerBuilder();  
Direcror mDirecror=new Direcror(mBuilder);  
mDirecror.CreateComputer("i7","Intel主板","mRam");//返回Computer實例對象

以上便完成了整個建造者模式的實現(xiàn)細節(jié)隧甚。

建造者模式精簡版
在現(xiàn)實開發(fā)中车荔,往往省去Director的角色,而直接使用一個Buider實例來進行對象的組裝戚扳。

建造者模式優(yōu)缺點
建造者模式的優(yōu)點:
(1)建造模式是將復雜的內(nèi)部創(chuàng)建封裝在內(nèi)部忧便,對于外部調(diào)用的人來說,只需要傳入建造者和建造工具帽借,對于內(nèi)部是如何建造成成品的珠增,調(diào)用者無需關心,良好的封裝性是建造者模式的優(yōu)點之一砍艾。
(2)建造者類邏輯獨立蒂教,易拓展。
建造者模式的缺點:
很明顯產(chǎn)生了多余的Build對象以及Dirextor對象脆荷,消耗了內(nèi)存凝垛。

實例二

參與者

1.Builder
  為創(chuàng)建一個Product對象的各個部件指定抽象接口。
2.ConcreteBuilder
  實現(xiàn)Builder的接口以構造和裝配該產(chǎn)品的各個部件蜓谋。
  定義并明確它所創(chuàng)建的表示梦皮。
  提供一個檢索產(chǎn)品的接口。
3.Director
  構造一個使用Builder接口的對象桃焕。
4.Product
  表示被構造的復雜對象剑肯。ConcreteBuilder創(chuàng)建該產(chǎn)品的內(nèi)部表示并定義它的裝配過程。
  包含定義組成部件的類覆旭,包括將這些部件裝配成最終產(chǎn)品的接口退子。

類圖

image.png

1.Builder

package com.nieshenkuan.creational.builderPattern.demo;

public interface PersonBuilder {

    void buildHead();

    void buildBody();

    void buildFoot();

    Person buildPerson();
    
}

2.ConcreteBuilder

package com.nieshenkuan.creational.builderPattern.demo;

public class ManBuilder implements PersonBuilder {

    Person person;

    public ManBuilder() {
        person = new Man();
    }

    public void buildBody() {
        person.setBody("建造男人的身體");
    }

    public void buildFoot() {
        person.setFoot("建造男人的腳");
    }

    public void buildHead() {
        person.setHead("建造男人的頭");
    }

    public Person buildPerson() {
        return person;
    }
}

3.Director

package com.nieshenkuan.creational.builderPattern.demo;

public class PersonDirector {

    public Person constructPerson(PersonBuilder pb) {
        pb.buildHead();
        pb.buildBody();
        pb.buildFoot();
        return pb.buildPerson();
    }
}

4.Product

package com.nieshenkuan.creational.builderPattern.demo;

public class Person {

    private String head;

    private String body;

    private String foot;

    public String getHead() {
        return head;
    }

    public void setHead(String head) {
        this.head = head;
    }

    public String getBody() {
        return body;
    }

    public void setBody(String body) {
        this.body = body;
    }

    public String getFoot() {
        return foot;
    }

    public void setFoot(String foot) {
        this.foot = foot;
    }
}
package com.nieshenkuan.creational.builderPattern.demo;

public class Man extends Person{

}

5.Test

package com.nieshenkuan.creational.builderPattern.demo;

public class Test {
    public static void main(String[] args) {
        PersonDirector pd = new PersonDirector();
        Person person = pd.constructPerson(new ManBuilder());
        System.out.println(person.getBody());
        System.out.println(person.getFoot());
        System.out.println(person.getHead());
    }
}

結果:

建造男人的身體
建造男人的腳
建造男人的頭

2018/04/25

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市型将,隨后出現(xiàn)的幾起案子寂祥,更是在濱河造成了極大的恐慌,老刑警劉巖七兜,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件丸凭,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機惜犀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門铛碑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人虽界,你說我怎么就攤上這事汽烦。” “怎么了莉御?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵撇吞,是天一觀的道長。 經(jīng)常有香客問我礁叔,道長牍颈,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任琅关,我火速辦了婚禮煮岁,結果婚禮上,老公的妹妹穿的比我還像新娘涣易。我一直安慰自己画机,他們只是感情好,可當我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布都毒。 她就那樣靜靜地躺著色罚,像睡著了一般。 火紅的嫁衣襯著肌膚如雪账劲。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天金抡,我揣著相機與錄音瀑焦,去河邊找鬼。 笑死梗肝,一個胖子當著我的面吹牛榛瓮,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播巫击,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼禀晓,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了坝锰?” 一聲冷哼從身側響起粹懒,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎顷级,沒想到半個月后凫乖,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年帽芽,在試婚紗的時候發(fā)現(xiàn)自己被綠了删掀。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡导街,死狀恐怖披泪,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情搬瑰,我是刑警寧澤款票,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站跌捆,受9級特大地震影響徽职,放射性物質發(fā)生泄漏。R本人自食惡果不足惜佩厚,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一姆钉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧抄瓦,春花似錦潮瓶、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至煞额,卻和暖如春思恐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背膊毁。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工胀莹, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人婚温。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓描焰,卻偏偏與公主長得像,于是被迫代替她去往敵國和親栅螟。 傳聞我的和親對象是個殘疾皇子荆秦,可洞房花燭夜當晚...
    茶點故事閱讀 42,762評論 2 345