天天看點

Builder模式的簡單實作

前言

Builder模式是将對象的建構和表示分離,好比建構一輛汽車,Builder是将部件群組裝過程分離,進而達到高内聚低耦合的目的。

使用場景

1.相同的方法,結果和執行順序有關。

2.多個部件都可以組裝到一個對象中,但是結果和這個部件有關。

3.産品非常複雜,或者初始化對象非常複雜(參數太多)。

簡單的代碼實作

Build分為Products産品類(産品的抽象類)、Builder類(規範産品的組建,但一般不實作具體過程)、ConcreteBuilder類(具體實作Builder類抽象方法)、Director類(統一組裝類,多數情況下都會省略該類)。

抽象一個生産過程:寶馬汽車的組裝,簡單分為幾步(組裝汽車外殼、組裝汽車中控、組裝汽車發動機等機械部件、内飾)。

Product類

package com.demo.bulider;

/**
 * Created by italkbb on 2017/12/13.
 */

public abstract class BMWCar {
    // 汽車外殼
    protected String mShell;
    // 汽車多媒體中控
    protected String mControl;
    // 汽車引擎和其他機械部件
    protected String mEngineAndOthers;
    // 汽車内飾
    protected String mDecoration;

    protected BMWCar(){

    }

    // 轉配汽車外殼
    public void setShell(String mShell) {
        this.mShell = mShell;
    }

    // 裝配汽車多媒體中控
    public void setControl(String mControl) {
        this.mControl = mControl;
    }

    // 裝配汽車機械部件
    public void setEngineAndOthers() {
    }

    // 裝配汽車内飾
    public void setDecoration(String mDecoration) {
        this.mDecoration = mDecoration;
    }
}
           

這個類定義産品,但是并不去裝配産品,隻是定義一個規則,那麼我們想要組裝一台X6汽車,這裡先抽象的設定X6和一般寶馬汽車最大的不同是發動機和機械元件,是以一上來我們的生産勞工先把各型号的發動機組裝好,這個是技術活,當然給進階工程師,不需要裝配勞工介入了。

package com.demo.bulider;

/**
 * Created by italkbb on 2017/12/13.
 */

public class BMWX6Car extends BMWCar{
    protected BMWX6Car(){

    }

    // 抽象為X6差別就是發動機等主要機械元件不一樣
    @Override
    public void setEngineAndOthers() {
        mEngineAndOthers = "寶馬X6專用發動機";
    }
}
           

寶馬汽車的主要部分已經好了,那麼把這個大架構給到組裝勞工去做外層處理,再定義一個生産規則:(Builder類)

package com.demo.bulider;

/**
 * Created by italkbb on 2017/12/13.
 */

public abstract class Builder {
    // 設定外殼
    public abstract Builder buliderShell(String shell);

    // 設定中控系統
    public abstract Builder buliderControl(String control);

    // 裝置機械元件
    public abstract Builder buliderEngineAndOthers();

    // 裝配内飾
    public abstract Builder buliderDecoration(String decoration);

    // 出廠汽車
    public abstract BMWCar create();
}
           

這當時組裝經理定義好了規則,下發給下一級員工。(下面說具體的Bulider類)

package com.demo.bulider;

/**
 * Created by italkbb on 2017/12/13.
 */

public class BMWX6Bulider extends Builder{
    private BMWCar mBMWCar = new BMWX6Car();

    @Override
    public Builder buliderShell(String shell) {
        mBMWCar.setShell(shell);
        return this;
    }

    @Override
    public Builder buliderControl(String control) {
        mBMWCar.setControl(control);
        return this;
    }

    @Override
    public Builder buliderEngineAndOthers() {
        mBMWCar.setEngineAndOthers();
        return this;
    }

    @Override
    public Builder buliderDecoration(String decoration) {
        mBMWCar.setDecoration(decoration);
        return this;
    }

    @Override
    public BMWCar create() {
        return mBMWCar;
    }
}
           

為了滿足生産線流水工作,組長把這個組裝過程封裝了一下,隻要員工按規矩來就能夠組裝好,而且組裝過程變得非常簡單,員工隻需要把組裝的原件放到指定位置就OK(Director類)。

package com.demo.bulider;

/**
 * Created by italkbb on 2017/12/13.
 */

public class Director {
    Builder mBulider = null;

    public Director(Builder builder){
        this.mBulider = builder;
    }

    /**
     * 統一組裝,簡化生産步驟
     * @param shell
     * @param control
     * @param decoration
     * @return
     */
    public BMWCar createCar(String shell,String control,String decoration){
        return mBulider.buliderShell(shell)
                .buliderControl(control)
                .buliderEngineAndOthers()
                .buliderDecoration(decoration).create();
    }
}
           

在實際開發中,其實可以不要Director類,因為組裝過程已經很簡單,員工知道掉builder的方法的教育成本已經很低了,是以開發中往往省略該類。

總結

builder模式在Android開發中也常常會用到,比如我之前加密解密Imageloader,裡面單例模式和Builder模式為主,還有Android源碼裡面AlertDialog.Builder類,這裡就不貼相關代碼了,說一下優缺點:該模式封裝的比較好,就像組裝汽車,組員工可以不必知道内部是怎麼實作的,隻需要按着說明書把相關零件放到指定位置;其次,如果要給Builder添加建構方法也變得很容易,這叫易于擴充吧。當然缺點也顯而易見:實作一個汽車組裝用到了五個類,其實真要寫,一個類都能夠實作這個過程,隻是代碼清晰度差點。我的郵箱[email protected],有錯誤還望指正。