設(shè)計模式之Builder模式

一、Builder模式的介紹

Builder模式是一步一步創(chuàng)建一個復(fù)雜對象的創(chuàng)建型模型,他允許用戶在不知道內(nèi)部構(gòu)建細節(jié)的情況下,可以更精細的控制對象的構(gòu)建流程;該模式是為了將構(gòu)建復(fù)雜對象的過程和他的不見解耦,是的構(gòu)建過程和部件的表示隔離開來;

二、Builder模式的定義

將一個復(fù)雜對象的構(gòu)建與他的表示分離,是的同樣的構(gòu)建過程可以創(chuàng)建不同的表示;

三、使用場景

1、相同的方法,不同的執(zhí)行順序,產(chǎn)生不同的事件結(jié)果時;
2、多個部件或零件都可以裝配到一個對象中,但是產(chǎn)生的運行結(jié)果又不相同時;
3、產(chǎn)品類非常復(fù)雜,或者產(chǎn)品類中的調(diào)用順序不同產(chǎn)生不同的作用;
4、當初始化一個對象特別復(fù)雜,如參數(shù)多,且很多參數(shù)都具有默認值時;

四、Builder模式的UML類圖

Builder模式的UML類圖.png

角色介紹:
Productc 產(chǎn)品類----產(chǎn)品的抽象類;
Builder----抽象Builder類,規(guī)范產(chǎn)品的組件、一般都由子類實現(xiàn)具體的實現(xiàn)過程;
ConcreteBuilder--------具體的Builder類;
Director---------統(tǒng)一組裝過程;

五、Builder模式的簡單實現(xiàn)

例子:計算機的組裝過程比較復(fù)雜,并且組裝順序不固定,為了便于理解,現(xiàn)在把計算機的組裝過程簡化為構(gòu)建主機、設(shè)置操作系統(tǒng)、設(shè)置顯示器三部分,然后通過Director和具體的Builder來構(gòu)建計算機對象:看下列實例:

/***
 *   Product產(chǎn)品類  :產(chǎn)品的抽象類
 */
public abstract class Computer {
    protected String mBoard ;       //主機
    protected String mDisplay ;     //顯示器
    protected String mOs ;          //操作系統(tǒng)
    //設(shè)置主機
    public void setBoard(String board) {
        mBoard = board;
    }
    //設(shè)置顯示器
    public void setDisplay(String display) {
        mDisplay = display;
    }
    //抽象操作系統(tǒng)的設(shè)置方法
    public abstract void  setOs();
    @Override
    public String toString() {
        return  "Computer { mBoard = " + mBoard + " , display = " + mDisplay + " , mOs = " + mOs + " }" + super.toString();
    }
}

/**
 * 具體的Computer類,Macbook
 */
public class MacBook extends Computer {
    protected MacBook() {}
    @Override
    public void setOs() {
        mOs = "Mac OS X 11.11";
    }
}

/**
 * 抽象的Builder類
 */
public abstract class Builder {
    public abstract void buildBoard(String board);
    public abstract void buildDisplay(String display);
    public abstract void buildOs();
    //創(chuàng)建Computer
    public abstract Computer create();
}

/**
* 具體的Builder類 MacBookBuilder
*/
public class MacBookBuilder extends Builder{
    private Computer mComputer = new MacBook();
    @Override
    public void buildBoard(String board) {
        mComputer.setBoard(board);
    }
    @Override
    public void buildDisplay(String display) {
        mComputer.setDisplay(display);
    }
    @Override
    public void buildOs() {
        mComputer.setOs();
    }
    @Override
    public Computer create() {
        return mComputer;
    }
}

/**
 * Created by admin on 2019/1/26.
 * Director 類, 負責構(gòu)造Computer
 */
public class Director {
    Builder mBuilder  = null;
    public Director(Builder builder){
        this.mBuilder = builder ;
    }
    public void construct(String board,String display){
        mBuilder.buildBoard(board);
        mBuilder.buildDisplay(display);
        mBuilder.buildOs();
    }
}


/**
 * 測試代碼
  */
public class TestBuilder {
    public static void main(String args[]){
        Builder mBuilder = new MacBookBuilder() ;
        Director mDirector =  new Director(mBuilder);
        mDirector.construct("主機","顯示器");
        System.out.println("Computer Info : " + mBuilder.create().toString());
    }
}

測試輸出結(jié)果為:

Computer Info : Computer { mBoard = 主機 , display = 顯示器 , mOs = Mac OS X 11.11 }sl.com.designmodedemo.builderdesign.MacBook@28d93b30
Computer Info : Computer { mBoard = 主機1 , display = 顯示器1 , mOs = Mac OS X 11.11 }sl.com.designmodedemo.builderdesign.MacBook@1b6d3586

這個示例中,通過具體的MacBookBuilder來構(gòu)建MacBook對象,而Director封裝了構(gòu)造復(fù)雜產(chǎn)品的過程,對外隱藏構(gòu)建細節(jié);Builder和Director一起講一個復(fù)雜對象的構(gòu)建和表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的對象;
值得注意的是,在顯示開發(fā)中Director類經(jīng)常別忽略,而直接使用一個Builder來進行對象的封裝,這個Builder通常是鏈式調(diào)用,他的關(guān)鍵點是每個setter方法都返回自身,即return this;這樣可以使得setter方法可以鏈式調(diào)用,如:

new MacBookBuilder().setA("a").setB("b").create();

通過這種形式不僅去除了Director角色,整個結(jié)構(gòu)也更加簡單,也能對Product對象的組裝有更精細的控制。

六、Android源碼中的Builder實現(xiàn)

最常用的就是ArertDialog.Builder,使用該Builder來構(gòu)建復(fù)雜的AlertDialog對象,我們先看一下最常用的使用例子:

        AlertDialog.Builder builder = new AlertDialog.Builder(this)
                .setIcon(R.mipmap.ic_launcher)
                .setTitle("對話框")
                .setMessage("顯示內(nèi)容")
                .setPositiveButton("確定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                    }
                }).setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                    }
                });
        AlertDialog dialog = builder.create();
        dialog.show();

感興趣的可以點進去看看他的源碼,再借助最開始的UML類圖介紹,相信可以看懂源碼中的Builder模式;

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容