一、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類圖

角色介紹:
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模式;