設計模式---Builder模式

1.什么是builder模式

? ?簡單解釋,在程序設計的時候,如果面對的對象屬性較多,對象復雜性比較大(例如對象包含對象)的情況,開發者選擇這種設計模式去設計一個類的時候,開發者可以在不知道類內部結構構建細節的情況下,清晰地控制對象構造流程。例如,一個person類擁有很多屬性的時候,最常見的比如name,age,weight,height等等。在這里兩個地方體現出builder模式的優勢:

(1)如果在創建一個person對象,只需要name、age屬性,則需要創建多一個包含這兩個屬性的構造方法。需求不一樣,構造方法就需要更多。累贅。
(2)對于普通的構造方法,當我們初始化weight、height兩個屬性的時候,我們一般會如下。

Person person = new Person("123","53");

如果屬性一多,我們根本很模糊知道weight是哪個。

2.模式適用范圍

(1)當創建復雜對象的算法應該獨立于該對象的組成部分以及它們的裝配方式時。
(2)當構造過程必須允許被構造的對象有不同的表示時。
(3)Builder模式要解決的也正是這樣的問題:
  當我們要創建的對象很復雜的時候(通常是由很多其他的對象組合而成),
  我們要復雜對象的創建過程和這個對象的表示(展示)分離開來,
  這樣做的好處就是通過一步步的進行復雜對象的構建,
  由于在每一步的構造過程中可以引入參數,使得經過相同的步驟創建最后得到的對象的展示不一樣。

3.具體應用

筆者這里通過汽車Car類對象包含引擎Engine類、導航Naviaror類、車輪Wheel類作為一個復雜性類說明Builder模式的應用。

(1)公有抽象類Car

 
/**
 * 車的抽象類 較復雜的對象,對象包含對象
 * Created by wsy on 2016/2/17.
 */
public abstract class Car {
 
    protected Engine mEngine;
    protected Navigator mNavigator;
    protected Wheel mWheel;
 
    public Car() {
    }
 
    public Car(Engine mEngine, Navigator mNavigator, Wheel mWheel) {
        this.mEngine = mEngine;
        this.mNavigator = mNavigator;
        this.mWheel = mWheel;
    }
 
    /**
    public Car(Engine mEngine) {
        this.mEngine = mEngine;
    }
 
    public Car(Engine mEngine, Navigator mNavigator) {
        this.mEngine = mEngine;
        this.mNavigator = mNavigator;
    }
     **/
 
    public Engine getmEngine() {
        return mEngine;
    }
 
    public void setmEngine(Engine mEngine) {
        this.mEngine = mEngine;
    }
 
    public Navigator getmNavigator() {
        return mNavigator;
    }
 
    public void setmNavigator(Navigator mNavigator) {
        this.mNavigator = mNavigator;
    }
 
    public Wheel getmWheel() {
        return mWheel;
    }
 
    public void setmWheel(Wheel mWheel) {
        this.mWheel = mWheel;
    }
 
    @Override
    public String toString() {
        return "Car{" +
                "mEngine=" + mEngine +
                ", mNavigator=" + mNavigator +
                ", mWheel=" + mWheel +
                '}';
    }
}

(2) 具體實現奔馳類

/**
 * 奔馳實體類
 * Created by wsy on 2016/2/17.
 */
public class BenzCar extends Car {
 
    public BenzCar() {
    }
 
    public BenzCar(Engine mEngine, Navigator mNavigator, Wheel mWheel) {
        super(mEngine, mNavigator, mWheel);
    }
 
    /**
    public BenzCar(Engine mEngine) {
        super(mEngine);
    }
 
    public BenzCar(Engine mEngine, Navigator mNavigator) {
        super(mEngine, mNavigator);
    }
     **/
 
    // 這里如果重寫了,直接通過this.mEngine,因為是父類projected類型,訪問不到,因此日志打印會為空值,多態
//    @Override
//    public void setmEngine(String mEngine) {
//        mEngine = "Benz Engine 2016";
//    }
}

(3)Car車構建類Builder

/**
 * 奔馳構建類
 * Created by wsy on 2016/2/17.
 */
public class BenzBuilder{
 
    private Car mCar = new BenzCar();
 
    public BenzBuilder builderEngine(Engine mEngine) {
        mCar.setmEngine(mEngine);
        return this;
    }
 
    public BenzBuilder builderWheel(Wheel mWheel) {
        mCar.setmWheel(mWheel);
        return this;
    }
 
    @Override
    public Builder builderNavigator(Navigator mNavigator) {
        mCar.setmNavigator(mNavigator);
        return this;
    }
 
    public Car onCreate() {
        return mCar;
    }
}

(4)引擎Engine類、導航Naviaror類、車輪Wheel類(這里構建類builder都是靜態內部類)

/**
 * 引擎實體類
 * Created by wsy on 2016/2/17.
 */
public class Engine {
 
    private String brand;
    private String power;
 
    public Engine(String brand, String power) {
        this.brand = brand;
        this.power = power;
    }
 
    public Engine() {
    }
 
    public String getBrand() {
        return brand;
    }
 
    public void setBrand(String brand) {
        this.brand = brand;
    }
 
    public String getPower() {
        return power;
    }
 
    public void setPower(String power) {
        this.power = power;
    }
 
    @Override
    public String toString() {
        return "Engine{" +
                "brand='" + brand + '\'' +
                ", power='" + power + '\'' +
                '}';
    }
 
    public static class EngineBuilder{
 
        private Engine mEngine = new Engine();
        private String brand;
        private String power;
 
        public EngineBuilder setBrand(String brand) {
            mEngine.setBrand(brand);
          return this;
        }
 
        public EngineBuilder setPower(String power) {
            mEngine.setPower(power);
            return this;
        }
 
        public Engine create(){
            return mEngine;
        }
 
    }
 
}
package cn.wsy.builder.simple.common;
 
/**
 * 導航儀實體類
 * Created by wsy on 2016/2/17.
 */
public class Navigator {
 
    private String brand;
    private String price;
 
    public Navigator(String brand, String price) {
        this.brand = brand;
        this.price = price;
    }
 
    public Navigator() {
    }
 
    public String getBrand() {
        return brand;
    }
 
    public void setBrand(String brand) {
        this.brand = brand;
    }
 
    public String getPrice() {
        return price;
    }
 
    public void setPrice(String price) {
        this.price = price;
    }
 
    @Override
    public String toString() {
        return "Navigator{" +
                "brand='" + brand + '\'' +
                ", price='" + price + '\'' +
                '}';
    }
 
    public static class NavigatorBuilder {
        private Navigator mNavigator = new Navigator();
        private String brand;
        private String price;
 
        public NavigatorBuilder setPrice(String price) {
            mNavigator.setPrice(price);
            return this;
        }
 
        public NavigatorBuilder setBrand(String brand) {
            mNavigator.setBrand(brand);
            return this;
        }
 
        public Navigator create(){
            return mNavigator;
        }
 
    }
 
}
package cn.wsy.builder.simple.common;
 
/**
 * 車輪實體類
 * Created by wsy on 2016/2/17.
 */
public class Wheel {
 
    private String brand;
    private String weight;
 
    public Wheel() {
    }
 
    public Wheel(String brand, String weight) {
        this.brand = brand;
        this.weight = weight;
    }
 
    public String getBrand() {
        return brand;
    }
 
    public void setBrand(String brand) {
        this.brand = brand;
    }
 
    public String getWeight() {
        return weight;
    }
 
    public void setWeight(String weight) {
        this.weight = weight;
    }
 
    @Override
    public String toString() {
        return "Wheel{" +
                "brand='" + brand + '\'' +
                ", weight='" + weight + '\'' +
                '}';
    }
 
    public static class WheelBuilder{
        private Wheel mWhell = new Wheel();
        private String brand;
        private String weight;
 
        public WheelBuilder setBrand(String brand) {
            mWhell.setBrand(brand);
           return this;
        }
 
        public WheelBuilder setWeight(String weight) {
            mWhell.setWeight(weight);
            return this;
        }
 
        public Wheel create(){
            return mWhell;
        }
    }
}

(4)測試方法
這里我們通過對比傳統構造方法來對比Builder構造的優勢:
1.如果類奔馳車類構造對象的時候不需要導航儀類,傳統的構造方法需要定義多一個構造方法,具體如下:

 public BenzCar(Engine mEngine, Wheel mWheel) {
           super(mEngine, mWheel);
 }

構造如下:

BenzCar car1 = new BenzCar(new Engine("321","321"),new Wheel("123","123"));

2.利用builder模式構造

//這種方式創建 可觀性清晰 構造器也可以減少
BenzBuilder builder = new BenzBuilder();//oncreate 可以拿到實體對象
BenzCar car = (BenzCar) builder
                       .builderEngine(new Engine.EngineBuilder().setBrand("brand").create())
                       .builderNavigator(new Navigator.NavigatorBuilder().setPrice("price").create()) 
                       .onCreate()
                      ;Log.i(TAG, car.toString());

這樣是不是更加清晰!需求改動、最初類屬性沒有修改的時候,可以直接不用修改類的構造方法,維護性更高!但是這種方式會嚴重增加的代碼量,所以各有優缺點!!

傻小孩b
20160217

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 上一篇文章設計模式-單例模式我們介紹了單例模式的幾種用法和優缺點,具體的我們需要結合項目中的場景去具體選擇。這一篇...
    i卓閱讀 337評論 0 1
  • Builder模式可以稱為建造者模式,它將一個復雜對象的構建和表示分離,同樣的構建過程可以創建不同的表示 適用場景...
    KevinLive閱讀 685評論 0 0
  • 模式的定義 將一個復雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。 模式的使用場景 相同的方法...
    狠哇塞的小伙子啊閱讀 367評論 0 1
  • Builder模式 定義:將一個復雜對象的構建和它的表示分離,使得同樣的構建過程可以創建不同的表示。 使用場景:(...
    ping_平閱讀 314評論 0 2
  • Retrofit中的Builder模式 1、Retrofit的構造 以上是Retrofit的構造過程(其實在Bui...
    gzfgeh閱讀 562評論 0 0