Android 的Builder模式

Builder的介紹:

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

Builder模式的定義:

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

對于android中 有個AlertDialog.Builder的使用想必大家都知道怎么用,這就是使用Builder來構(gòu)建復(fù)雜的AlertDialog對象。例如下面的代碼

 //顯示基本的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)擊了對話框上的Button1");  
                    }  
                });  
        builder.setNeutralButton("Button2",  
                new DialogInterface.OnClickListener() {  
                    public void onClick(DialogInterface dialog, int whichButton) {  
                        setTitle("點(diǎn)擊了對話框上的Button2");  
                    }  
                });  
        builder.setNegativeButton("Button3",  
                new DialogInterface.OnClickListener() {  
                    public void onClick(DialogInterface dialog, int whichButton) {  
                        setTitle("點(diǎn)擊了對話框上的Button3");  
                    }  
                });  
        builder.create().show();  // 構(gòu)建AlertDialog, 并且顯示
    }

創(chuàng)建完之后的對話框效果如圖:


1.png

Builder模式的好處就是
1,良好的封裝性, 使用建造者模式可以使客戶端不必知道產(chǎn)品內(nèi)部組成的細(xì)節(jié);
2,建造者獨(dú)立,容易擴(kuò)展;
3,在對象創(chuàng)建過程中會使用到系統(tǒng)中的一些其它對象,這些對象在產(chǎn)品對象的創(chuàng)建過程中不易得到。
從代碼的結(jié)構(gòu)上也是看起來很順眼。

但是

所以 Builder模式的使用場景,一般如下:
1,相同的方法,不同的執(zhí)行順序,產(chǎn)生不同的事件結(jié)果時;
2,多個部件或零件,都可以裝配到一個對象中,但是產(chǎn)生的運(yùn)行結(jié)果又不相同時;
3,產(chǎn)品類非常復(fù)雜,或者產(chǎn)品類中的調(diào)用順序不同產(chǎn)生了不同的效能,這個時候使用建造者模式非常合適;
4,當(dāng)初始化一個對象特別復(fù)雜,如參數(shù)多,且很多參數(shù)都具有默認(rèn)值時。

下面以組裝電腦為例來演示一下簡單且經(jīng)典的builder模式。

package com.sx.test.builder;

/**
 * Computer產(chǎn)品抽象類, 為了例子簡單, 只列出這幾個屬性
 *
 * @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)建對象
     *
     * @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對象,而Director封裝了構(gòu)建復(fù)雜產(chǎn)品對象的過程,對外隱藏構(gòu)建細(xì)節(jié)。Builder與Director一起將一個復(fù)雜對象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的對象。
不過在現(xiàn)實開發(fā)中,Director角色經(jīng)常會被省略。而直接使用一個Builder來進(jìn)行對象的封裝,這個Builder通常為鏈?zhǔn)秸{(diào)用,他的關(guān)鍵點(diǎn)是每個setter方法都返回自身,也就是return this,這樣使得setter方法可以鏈?zhǔn)秸{(diào)用,代碼大致如下:
new TestBuilder().setA("A").setB("B").create();
通過這種形式不僅去除了Director角色,整個結(jié)構(gòu)也更加簡單,也能對Product對象的組裝過程有更精細(xì)的控制。

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

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

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