Java設計模式之建造者模式(Builder)

總李寫程式碼發表於2016-05-30

前言:

    最近一直在學習okHttp,也對其做了一些整理,okHttp和Retrofit結合大大加速我們的開發效率,原始碼裡面採用了很多設計模式,今天我們來學習一下其中的設計模式之一建造者模式。

建造者模式

    將一個複雜物件的構建與它的表示分離,使得同樣的構建過程可以建立不同的表示。

 使用場景:

  • 當建立複雜物件的演算法應該獨立於該物件的組成部分以及它們的裝配方式時。

  • 當構造過程必須允許被構造的物件有不同的表示時。

 

主要組成部分

  • Builder 是為建立一個product物件的各個部件指定的抽象介面

  • ConcreteBuilder 實現Builder的介面以構造和裝配該產品的各個部件

  • Director 他是構建一個使用Builder介面的物件

  • Product 表示被構造的複雜物件

 

舉例說明

    對於上面的描述多多少少會讓人感覺一頭霧水,接下來我們以一個簡單的例子來說明一下。模擬一個需求:李先生想要託人建造一個馬力為300,輪胎尺寸為18的suv,我們該如何通過建造者模式滿足李先生的需求呢。

1.)第一步先基於李先生的要求 確定這部suv的部件

Car類

public class Car {
    private final Engine engine;
    private final Tyre tyre;

    Car() {
        this(new Builder());
    }

    Car(final Engine engine, final Tyre tyre) {
        this.engine = engine;
        this.tyre = tyre;
    }

    Car(Builder builder) {
        this.engine = builder.engine;
        this.tyre = builder.tyre;
    }

    public void startDrive() {
        this.engine.startRun();
        this.tyre.startGo();
    }

 }

 

Engine類

final class Engine {

    private int power;

    Engine(int power) {
        this.power = power;
    }

    Engine() {
        this.power = 235;
    }

    public void startRun() {
        Log.e("startRun", "startRun----->" + power);
    }

}

Tyre類

final class Tyre {

    private int size;

    Tyre(int size) {
        this.size = size;
    }

    Tyre() {
        this.size = 18;
    }

    public void startGo() {
        Log.e("startRun", "startGo----->" + size);
    }
}

 

2.)第二步我們按照需求安排工序
 interface ICar {

    /**
     * 建造一個發動機
     * @param power
     */
    void buildEngine(int power);

    /**
     * 安裝一個輪胎
     * @param size
     */
    void buildTyre(int size);

    /**
     * 組裝車輛
     * @return
     */
    Car build();
}
3.)第三步安排建造者生產
 public static class Builder implements ICar {
        private Engine engine;
        private Tyre tyre;

        private Builder(Car car) {
            this.engine = car.engine;
            this.tyre = car.tyre;
        }

        public Builder() {
            engine = new Engine();
            tyre = new Tyre();
        }

        @Override
        public void buildEngine(int power) {
            this.engine = new Engine(power);
        }

        @Override
        public void buildTyre(int size) {
            this.tyre = new Tyre(size);
        }

        @Override
        public Car build() {
            return new Car(this);
        }
    }
4.)生產完畢交付到李先生手裡
        Car.Builder builder = new Car.Builder();
        builder.buildEngine(120);
        builder.buildTyre(30);
        Car car = builder.build();
        car.startDrive();
5.)一般情況下Director ,Product 放在一個類裡實現 詳細程式碼如下
public class Car {
    private final Engine engine;
    private final Tyre tyre;

    Car() {
        this(new Builder());
    }

    Car(final Engine engine, final Tyre tyre) {
        this.engine = engine;
        this.tyre = tyre;
    }

    Car(Builder builder) {
        this.engine = builder.engine;
        this.tyre = builder.tyre;
    }

    public void startDrive() {
        this.engine.startRun();
        this.tyre.startGo();
    }

    public Builder newBuilder() {
        return new Builder(this);
    }

    public static class Builder implements ICar {
        private Engine engine;
        private Tyre tyre;

        private Builder(Car car) {
            this.engine = car.engine;
            this.tyre = car.tyre;
        }

        public Builder() {
            engine = new Engine();
            tyre = new Tyre();
        }

        @Override
        public void buildEngine(int power) {
            this.engine = new Engine(power);
        }

        @Override
        public void buildTyre(int size) {
            this.tyre = new Tyre(size);
        }

        @Override
        public Car build() {
            return new Car(this);
        }
    }
}

小結

   整個例子裡面特別注意一下類的許可權已經建構函式的許可權控制,其實李先生從下單到提車對整個過程的細節一無所知,這樣就有效的實現建造者模式的好處,很好的讓造車其中各個複雜的環節與造車剝離開。

 

相關文章