1、使用場景
bash
①、相同的方法,不一樣的執行順序,產品不一樣的時間結果時。ide
②、多個部件或零件,均可以裝配到一個對象中,可是產生的運行結果又不相同時。ui
③、產品類很是複雜,或者產品類中的調用順序不一樣產生了不一樣的做用,這個時候使用建造者模式很是合適。this
④、當初始化一個對象特別複雜,如參數多,且不少參數都具備默認值時。spa
⑤、將一個複雜對象的構建與它的表示分離,使得一樣的構建過程能夠建立不一樣的表示。操作系統
計算機的組裝過程較爲複雜,且組裝順序倒是不固定的,爲了易於理解,咱們把計算機組裝的過程簡化爲構建主機、設置操做系統、設置顯示器3個部分,而後經過Director(統一組裝過程)和具體的Builder來構建計算機對象。代碼以下:code
/**
* User:xijiufu
* Time:2016/4/4,17:29
* Function :
*/
public abstract class Computer {
protected String mBoard;
protected String mDisplay;
protected String mOS;
protected Computer() {
}
//設置cpu核心數
public void setBoard(String mBoard) {
this.mBoard = mBoard;
}
//設置內存
public void setmDisplay(String mDisplay) {
this.mDisplay = mDisplay;
}
//設置操做系統
public abstract void setOS();
@Override
public String toString() {
return "Computer{" +
"mOS='" + mOS + '\'' + ", mDisplay='" + mDisplay + '\'' + ", mBoard='" + mBoard + '\'' +
'}';
}
}複製代碼
/**
* User:xijiufu
* Time:2016/4/4,17:34
* Function :
*/
public class MacBook extends Computer {
protected MacBook() {
}
@Override
public void setOS() {
mOS = "Mac OS X 10.10";
}
}複製代碼
/**
* User:xijiufu
* Time:2016/4/4,17:35
* Function :
*/
public abstract class Builder {
//設置主機
public abstract void buildBoard(String board);
//設置顯示器
public abstract void buildDisplay(String display);
//設置操做系統
public abstract void buildOS();
//建立Computer
public abstract Computer create();
}複製代碼
/**
* User:xijiufu
* Time:2016/4/4,17:41
* Function :
*/
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.setmDisplay(display);
}
@Override
public void buildOS() {
mComputer.setOS();
}
@Override
public Computer create() {
return mComputer;
}
}複製代碼
/**
* User:xijiufu
* Time:2016/4/4,17:44
* Function : 構造
*/
public class Director {
private 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();
}
}複製代碼
/**
* User:xijiufu
* Time:2016/4/4,17:46
* Function : Build構建模式
*/
public class TestBuilder extends InstrumentationTestCase {
public static void main(String[] strings) {
//構造器
Builder builder = new MacBookBuilder();
//Director
Director pcDirector = new Director(builder);
//封裝構建過程,4核、內存2G Mac系統
pcDirector.construct("英特爾主板", "AOC顯示器");
//構建計算機,輸出相關信息
System.out.println("Computer Info:" + builder.create().toString());
}
}複製代碼
輸出結果:對象
Computer Info:Computer{mOS='Mac OS X 10.10', mDisplay='AOC顯示器', mBoard='英特爾主板'}內存
上述實例中,經過具體的MacbookBuilder來構建Macbook對象,而Director封裝了構建複雜產品對象的過程,對外隱藏構建細節。Builder與Director一塊兒將一個複雜對象的構建與它的表示分離,使得一樣的構建過程能夠建立不一樣的對象。開發
值得注意的是,在現實開發過程當中,Director角色常常會被忽略。而直接使用一個Builder來進行對象的組裝,這個Builder一般爲鏈式調用,它的關鍵點是每一個setter方法都返回自身,也就是return this,這樣就使得setter方法能夠鏈式調用,代碼大體以下:
new TestBuilder().setA("A").setB("B").create();
經過這種形式不只去除了Director角色,整個結構也更加簡單,也能對Product對象的組裝過程更精細的控制。
在Android源碼中,最經常使用到的Builder模式就是AlertDialog.Builder,使得該Builder來構造複雜的AlertDialog對象。