「補課」進行時:設計模式(4)——建造者模式

1. 前文彙總

「補課」進行時:設計模式系列

2. 建造者模式定義

建造者模式(Builder Pattern)也叫做生成器模式,其定義如下:

Separate the construction of a complex object from its representation sothat the same construction process can create different representations.(將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。)

通用類圖:

  • Product: 產品類,通常是實現了模板方法模式,也就是有模板方法和基本方法。
  • Builder: 抽象建造者,規範產品的組建,一般是由子類實現。
  • ConcreteBuilder: 具體建造者,實現抽象類定義的所有方法,並且返回一個組建好的對象。
  • Director: 導演類,負責安排已有模塊的順序,然後告訴 Builder 開始建造。

通用代碼示例:

Product 產品類:

public class Product {
    public void doSomething() {
        // 業務處理
    }
}

Builder 抽象建造者:

public abstract class Builder {
    // 設置產品不同的部分,用來獲得不同的產品
    abstract void setPart();
    // 建造產品
    abstract Product buildProduct();
}

ConcreteBuilder 具體建造者:

public class ConcreteProduct extends Builder{
    private Product product = new Product();
    @Override
    void setPart() {
        // 獨特的處理邏輯
    }

    @Override
    Product buildProduct() {
        return product;
    }
}

Director 導演類:

public class Director {
    private Builder builder = new ConcreteProduct();
    public Product getProduct() {
        builder.setPart();
        // 設置不同的 part ,生產不同的零件
        return builder.buildProduct();
    }
}

3. 通過建造者模式造一輛共享單車

接下來使用建造者模式造一輛共享單車。

經歷過共享單車大戰之後,現在共享單車還在運營活着的也沒幾家了,在大街上比較常看到的有美團單車和哈羅單車,先創建一個抽象的產品類:

public abstract class AbstractBike {
    // 各個零件製造順序
    private ArrayList<String> sequence = new ArrayList<> ();
    // 自行車車架
    protected abstract void frame();
    // 自行車座位
    protected abstract void seat();
    // 自行車輪子
    protected abstract void tire();
    // 生產方法
    final public void createBike() {
        for (int i = 0; i < sequence.size(); i++) {
            String actionName = this.sequence.get(i);
            if (actionName.equalsIgnoreCase("frame")) {
                this.frame();
            } else if (actionName.equalsIgnoreCase("seat")) {
                this.seat();
            } else if (actionName.equalsIgnoreCase("tire")) {
                this.tire();
            }
        }
    }

    final public void setSequence(ArrayList sequence) {
        this.sequence = sequence;
    }
}

在這個產品類中,定義了三個零件和一個零件的製造順序,在單車的生產方法中,通過循環制造順序,可以製造的順序進行控制。

接下來是兩個具體的產品類:

public class HelloBike extends AbstractBike {
    @Override
    protected void frame() {
        System.out.println("現在開始生產一個哈羅車架");
    }

    @Override
    protected void seat() {
        System.out.println("現在開始生產一個哈羅座位");
    }

    @Override
    protected void tire() {
        System.out.println("現在開始生產兩個哈羅輪胎");
    }
}

public class MeituanBike extends AbstractBike {
    @Override
    protected void frame() {
        System.out.println("現在開始生產一個美團車架");
    }

    @Override
    protected void seat() {
        System.out.println("現在開始生產一個美團座位");
    }

    @Override
    protected void tire() {
        System.out.println("現在開始生產兩個美團輪胎");
    }
}

接下來創建一個抽象的 Builder :

public abstract class Builder {
    // 創建一個生產順序模型
    public abstract void setSequence(ArrayList<String> sequence);
    // 生產完成後獲取這個車輛模型
    public abstract AbstractBike getBike();
}

然後是兩個具體的建造者:

public class HelloBuilder extends Builder {
    private HelloBike helloBike = new HelloBike();
    @Override
    public void setSequence(ArrayList<String> sequence) {
        this.helloBike.setSequence(sequence);
    }

    @Override
    public AbstractBike getBike() {
        return this.helloBike;
    }
}

public class MeituanBuilder extends Builder {
    private MeituanBike meituanBike = new MeituanBike();
    @Override
    public void setSequence(ArrayList<String> sequence) {
        this.meituanBike.setSequence(sequence);
    }

    @Override
    public AbstractBike getBike() {
        return this.meituanBike;
    }
}

最後是一個導演類:

public class Director {
    private ArrayList<String> sequence = new ArrayList<>();
    private HelloBuilder helloBuilder = new HelloBuilder();
    private MeituanBuilder meituanBuilder = new MeituanBuilder();

    public HelloBike getHelloBike() {
        this.sequence.clear();
        // 自定義生產的順序
        this.sequence.add("frame");
        this.sequence.add("seat");
        this.sequence.add("tire");
        this.helloBuilder.setSequence(sequence);
        return (HelloBike) this.helloBuilder.getBike();
    }

    public MeituanBike getMeituanBike() {
        this.sequence.clear();
        // 定義生產的順序
        this.sequence.add("seat");
        this.sequence.add("tire");
        this.sequence.add("frame");
        this.meituanBuilder.setSequence(sequence);
        return (MeituanBike) this.meituanBuilder.getBike();
    }
}

然後寫一個 Test 類進行一下測試:

public class Test {
    public static void main(String[] args) {
        Director director = new Director();
        director.getHelloBike().createBike();
    }
}

運行結果是:

現在開始生產一個哈羅車架
現在開始生產一個哈羅座位
現在開始生產兩個哈羅輪胎

最後放一個這個示例的 UML 類圖:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章