Builder的介紹:
Builder模式是 一步一步創(chuàng)建一個(gè)復(fù)雜對(duì)象的創(chuàng)建型模式,它允許用戶在不知道內(nèi)部構(gòu)建細(xì)節(jié)的情況下木蹬,可以更精細(xì)地控制對(duì)象的構(gòu)造流程进泼。該模式是為了將構(gòu)建復(fù)雜對(duì)象的過程和它的部件解耦撵儿,使得構(gòu)建過程和部件的表示隔離開來渤闷。
Builder模式的定義:
將一個(gè)復(fù)雜對(duì)象的構(gòu)建與它的表示分離甘晤,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示含潘。
對(duì)于android中 有個(gè)AlertDialog.Builder的使用想必大家都知道怎么用,這就是使用Builder來構(gòu)建復(fù)雜的AlertDialog對(duì)象安皱。例如下面的代碼
//顯示基本的AlertDialog
private void showDialog(Context context) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setIcon(R.drawable.icon);
builder.setTitle("Title");
builder.setMessage("Message");
builder.setPositiveButton("Button1",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
setTitle("點(diǎn)擊了對(duì)話框上的Button1");
}
});
builder.setNeutralButton("Button2",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
setTitle("點(diǎn)擊了對(duì)話框上的Button2");
}
});
builder.setNegativeButton("Button3",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
setTitle("點(diǎn)擊了對(duì)話框上的Button3");
}
});
builder.create().show(); // 構(gòu)建AlertDialog调鬓, 并且顯示
}
創(chuàng)建完之后的對(duì)話框效果如圖:
Builder模式的好處就是
1,良好的封裝性酌伊, 使用建造者模式可以使客戶端不必知道產(chǎn)品內(nèi)部組成的細(xì)節(jié);
2缀踪,建造者獨(dú)立居砖,容易擴(kuò)展;
3驴娃,在對(duì)象創(chuàng)建過程中會(huì)使用到系統(tǒng)中的一些其它對(duì)象奏候,這些對(duì)象在產(chǎn)品對(duì)象的創(chuàng)建過程中不易得到。
從代碼的結(jié)構(gòu)上也是看起來很順眼唇敞。
但是
所以 Builder模式的使用場(chǎng)景蔗草,一般如下:
1,相同的方法疆柔,不同的執(zhí)行順序咒精,產(chǎn)生不同的事件結(jié)果時(shí);
2旷档,多個(gè)部件或零件模叙,都可以裝配到一個(gè)對(duì)象中,但是產(chǎn)生的運(yùn)行結(jié)果又不相同時(shí)鞋屈;
3范咨,產(chǎn)品類非常復(fù)雜,或者產(chǎn)品類中的調(diào)用順序不同產(chǎn)生了不同的效能厂庇,這個(gè)時(shí)候使用建造者模式非常合適渠啊;
4,當(dāng)初始化一個(gè)對(duì)象特別復(fù)雜权旷,如參數(shù)多替蛉,且很多參數(shù)都具有默認(rèn)值時(shí)。
下面以組裝電腦為例來演示一下簡單且經(jīng)典的builder模式。
package com.sx.test.builder;
/**
* Computer產(chǎn)品抽象類, 為了例子簡單, 只列出這幾個(gè)屬性
*
* @author mrsimple
*/
public abstract class Computer {
protected int mCpuCore = 1;
protected int mRamSize = 0;
protected String mOs = "Dos";
protected Computer() {
}
// 設(shè)置CPU核心數(shù)
public abstract void setCPU(int core);
// 設(shè)置內(nèi)存
public abstract void setRAM(int gb);
// 設(shè)置操作系統(tǒng)
public abstract void setOs(String os);
@Override
public String toString() {
return "Computer [mCpuCore=" + mCpuCore + ", mRamSize=" + mRamSize + ", mOs=" + mOs + "]";
}
}
package com.sx.test.builder;
/**
* Apple電腦
*/
public class AppleComputer extends Computer {
protected AppleComputer() {
}
@Override
public void setCPU(int core) {
mCpuCore = core;
}
@Override
public void setRAM(int gb) {
mRamSize = gb;
}
@Override
public void setOs(String os) {
mOs = os;
}
}
package com.sx.test.builder;
/**
* builder抽象類
*
*/
public abstract class Builder {
// 設(shè)置CPU核心數(shù)
public abstract void buildCPU(int core);
// 設(shè)置內(nèi)存
public abstract void buildRAM(int gb);
// 設(shè)置操作系統(tǒng)
public abstract void buildOs(String os);
// 創(chuàng)建Computer
public abstract Computer create();
}
package com.sx.test.builder;
public class ApplePCBuilder extends Builder {
private Computer mApplePc = new AppleComputer();
@Override
public void buildCPU(int core) {
mApplePc.setCPU(core);
}
@Override
public void buildRAM(int gb) {
mApplePc.setRAM(gb);
}
@Override
public void buildOs(String os) {
mApplePc.setOs(os);
}
@Override
public Computer create() {
return mApplePc;
}
}
package com.sx.test.builder;
public class Director {
Builder mBuilder = null;
/**
*
* @param builder
*/
public Director(Builder builder) {
mBuilder = builder;
}
/**
* 構(gòu)建對(duì)象
*
* @param cpu
* @param ram
* @param os
*/
public void construct(int cpu, int ram, String os) {
mBuilder.buildCPU(cpu);
mBuilder.buildRAM(ram);
mBuilder.buildOs(os);
}
}
package com.sx.test.builder;
public class Test {
public static void main(String[] args) {
// 構(gòu)建器
Builder builder = new ApplePCBuilder();
// Director
Director pcDirector = new Director(builder);
// 封裝構(gòu)建過程, 4核, 內(nèi)存2GB, Mac系統(tǒng)
pcDirector.construct(4, 2, "Mac OS X 10.9.1");
// 構(gòu)建電腦, 輸出相關(guān)信息
System.out.println("Computer Info : " + builder.create().toString());
}
}
結(jié)果輸出:Computer info : Computer [mCpuCore=4, mRamSize=2, mOs=Mac OS X 10.9.1]
上述示例中灭返,通過具體的ApplePCBuilder來構(gòu)建AppleComputer對(duì)象盗迟,而Director封裝了構(gòu)建復(fù)雜產(chǎn)品對(duì)象的過程,對(duì)外隱藏構(gòu)建細(xì)節(jié)熙含。Builder與Director一起將一個(gè)復(fù)雜對(duì)象的構(gòu)建與它的表示分離罚缕,使得同樣的構(gòu)建過程可以創(chuàng)建不同的對(duì)象。
不過在現(xiàn)實(shí)開發(fā)中怎静,Director角色經(jīng)常會(huì)被省略邮弹。而直接使用一個(gè)Builder來進(jìn)行對(duì)象的封裝,這個(gè)Builder通常為鏈?zhǔn)秸{(diào)用蚓聘,他的關(guān)鍵點(diǎn)是每個(gè)setter方法都返回自身腌乡,也就是return this,這樣使得setter方法可以鏈?zhǔn)秸{(diào)用夜牡,代碼大致如下:
new TestBuilder().setA("A").setB("B").create();
通過這種形式不僅去除了Director角色与纽,整個(gè)結(jié)構(gòu)也更加簡單,也能對(duì)Product對(duì)象的組裝過程有更精細(xì)的控制塘装。