前言
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],有錯誤還望指正。