Java設計模式之建造者模式

Java設計設計模式之建造者模式

1. 簡介

造者模式(Builder Pattern):將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。

建造者模式是一步一步創建一個複雜的對象,它允許用戶只通過指定複雜對象的類型和內容就可以構建它們,用戶不需要知道內部的具體構建細節。建造者模式屬於對象創建型模式。根據中文翻譯的不同,建造者模式又可以稱爲生成器模式。

2. 建造者模式中的角色

建造者模式包含如下角色:

  • Builder:抽象建造者
  • ConcreteBuilder:具體建造者
  • Director:指揮者
  • Product:產品角色

3. 情景實例

我們模擬實現一個筆記本的CPU、硬盤、顯卡的安裝生產過程。

3.1 代碼實現

產品 ==> 對應建造者中的 Product 產品角色

/**
 * 一個具體的產品
 * @author long
 */
public class Computer {

    /**
     * cpu
     */
    private String cpu;
    /**
     * 硬盤
     */
    private String hdd;
    /**
     * 顯卡
     */
    private String gpu;

    // 省略set、get、構造函數、toStirng()方法

}

電腦抽象建造者 ==> 對象建造者模式中 Builder。

/**
 * 用來創建一個Product對象的各個部件指定的接口或者抽象類
 * @author long
 */
public abstract class AbstractComputerBuilder {

    /**
     * 構建CPU
     */
    public abstract void buildCpu();

    /**
     * 構建硬盤
     */
    public abstract void buildHdd();

    /**
     * 構建顯卡
     */
    public abstract void buildGpu();

    /**
     * 建造好筆記本,將筆記本返回
     * @return
     */
    public abstract Computer builder();

}

蘋果筆記本具體產品 ==> 對應建造者模式中 ConcreteBuilder

/**
 * 具體建造者,
 * 實現接口或抽象, 構建和裝配各個配件
 * @author long
 */
public class MacComputer extends AbstractComputerBuilder {

    private Computer computer = new Computer();

    /**
     * 構建CPU
     */
    @Override
    public void buildCpu() {
        System.out.println("裝入I9處理器");
        computer.setCpu("i9");
    }

    /**
     * 構建硬盤
     */
    @Override
    public void buildHdd() {
        System.out.println("裝入500G固態硬盤");
        computer.setHdd("500G");
    }

    /**
     * 構建顯卡
     */
    @Override
    public void buildGpu() {
        System.out.println("裝入1060Ti顯卡");
        computer.setGpu("1060Ti");
    }

    /**
     * 建造好筆記本,將筆記本返回
     *
     * @return
     */
    @Override
    public Computer builder() {
        System.out.print("開始安裝PC : ");
        return computer;
    }
}

小米筆記本具體產品 ==> 對應建造者模式中 ConcreteBuilder

/**
 * 具體建造者,
 * 實現接口或抽象, 構建和裝配各個配件
 * @author long
 */
public class MiComputer extends AbstractComputerBuilder {

    private Computer computer = new Computer();

    /**
     * 構建CPU
     */
    @Override
    public void buildCpu() {
        System.out.println("裝入i7處理器");
        computer.setCpu("i7");
    }

    /**
     * 構建硬盤
     */
    @Override
    public void buildHdd() {
        System.out.println("裝入256G固態");
        computer.setHdd("256G");
    }

    /**
     * 構建顯卡
     */
    @Override
    public void buildGpu() {
        System.out.println("裝入MAX250顯卡");
        computer.setGpu("MAX250");
    }

    /**
     * 建造好筆記本,將筆記本返回
     *
     * @return
     */
    @Override
    public Computer builder() {
        System.out.println("開始安裝PC  ===>  ");
        return computer;
    }
}

筆記本的建造指揮者 ==> 對應建造者模式中 Director 指揮者。

/**
 * 構建一個使用Builder接口的對象,他主要用於創建一個複雜的對象,他主要有兩個作用,
 * 1. 隔離用戶和對象的生成過程,
 * 2. 負責控制產品對象的生產過程
 * @author long
 */
public class ComputerDirector {

    private AbstractComputerBuilder builder = null;

    public ComputerDirector(AbstractComputerBuilder builder) {
        this.builder = builder;
    }

    public Computer computerBuilder() {
        builder.buildCpu();
        builder.buildHdd();
        builder.buildGpu();
        return builder.builder();
    }
}

客戶端

/**
 * @author long
 */
public class Client {
    public static void main(String[] args) {
        MacComputer macComputer = new MacComputer();
        ComputerDirector computerDirector = new ComputerDirector(macComputer);
        Computer computer = computerDirector.computerBuilder();
        System.out.println(computer);
    }
}

3.2 UML類圖

在這裏插入圖片描述

3.3 模式分析

抽象建造者類中定義了產品的創建方法和返回方法;

建造者模式的結構中還引入了一個指揮者類Director,該類的作用主要有兩個:一方面它隔離了客戶與生產過程;另一方面它負責控制產品的生成過程。指揮者針對抽象建造者編程,客戶端只需要知道具體建造者的類型,即可通過指揮者類調用建造者的相關方法,返回一個完整的產品對象

在客戶端代碼中,無須關心產品對象的具體組裝過程,只需確定具體建造者的類型即可,建造者模式將複雜對象的構建與對象的表現分離開來,這樣使得同樣的構建過程可以創建出不同的表現。

4. 建造者模式的變形

將建造類設置爲內部類,可以顯示鏈式調用,省略了抽象建造者和指揮者。

public class Computer {

    private String cpu;
    private String hdd;
    private String gpu;

    public Computer(Builder builder) {
        cpu = builder.cpu;
        hdd = builder.hdd;
        gpu = builder.gpu;
    }

    public static class Builder {
        private String cpu;
        private String hdd;
        private String gpu;

        public Builder setCpu(String cpu) {
            this.cpu = cpu;
            return this;
        }

        public Builder setHdd(String hdd) {
            this.hdd = hdd;
            return this;
        }

        public Builder setGpu(String gpu) {
            this.gpu = gpu;
            return this;
        }

        public Computer build() {
            return new Computer(this);
        }
    }

    @Override
    public String toString() {
        return "Computer{" +
                "cpu='" + cpu + '\'' +
                ", hdd='" + hdd + '\'' +
                ", gpu='" + gpu + '\'' +
                '}';
    }
}

調用

public class Client {
    public static void main(String[] args) {
        Computer computer = new Computer.Builder().setCpu("i7").setGpu("1060Ti").setHdd("500G").build();
        System.out.println(computer);
    }
}

5. 優缺點

5.1 優點

  • 建造者模式的封裝性很好。使用建造者模式可以有效的封裝變化,在使用建造者模式的場景中,一般產品類和建造者類是比較穩定的,因此,將主要的業務邏輯封裝在導演類中對整體而言可以取得比較好的穩定性。

  • 在建造者模式中,客戶端不必知道產品內部組成的細節,將產品本身與產品的創建過程解耦,使得相同的創建過程可以創建不同的產品對象。

  • 可以更加精細地控制產品的創建過程 。將複雜產品的創建步驟分解在不同的方法中,使得創建過程更加清晰,也更方便使用程序來控制創建過程。

  • 其次,建造者模式很容易進行擴展。如果有新的需求,通過實現一個新的建造者類就可以完成,基本上不用修改之前已經測試通過的代碼,因此也就不會對原有功能引入風險。符合開閉原則。

5.2 缺點

建造者模式所創建的產品一般具有較多的共同點,其組成部分相似,如果產品之間的差異性很大,則不適合使用建造者模式,因此其使用範圍受到一定的限制。

如果產品的內部變化複雜,可能會導致需要定義很多具體建造者類來實現這種變化,導致系統變得很龐大。

6. 使用場景

  • 需要生成的產品對象有複雜的內部結構,每一個內部成分本身也可以是對象,也可以僅僅是一個對象(產品)的一個組成部分。
  • 需要生成的產品對象的屬性相互依賴。建造模式可以強制實行一種分步驟進行的建造過程。因此,如果產品對象的一個屬性必須在另外一個屬性賦值之後纔可以被賦值,那麼,使用建造者模式是一個很好的設計思想。
  • 隔離複雜對象的創建和使用,並使得相同的創建過程可以創建不同的產品。

7. 工廠模式的區別

建造者模式與工廠模式是極爲相似的,總體上,建造者模式僅僅只比工廠模式多了一個“指揮者”的角色。在建造者模式的類圖中,假如把這個指揮者類看做是最終調用的客戶端,那麼圖中剩餘的部分就可以看作是一個簡單的工廠模式了。

使用場景

  • 需要生成的產品對象有複雜的內部結構,每一個內部成分本身也可以是對象,也可以僅僅是一個對象(產品)的一個組成部分。
  • 需要生成的產品對象的屬性相互依賴。建造模式可以強制實行一種分步驟進行的建造過程。因此,如果產品對象的一個屬性必須在另外一個屬性賦值之後纔可以被賦值,那麼,使用建造者模式是一個很好的設計思想。
  • 隔離複雜對象的創建和使用,並使得相同的創建過程可以創建不同的產品。

7. 工廠模式的區別

建造者模式與工廠模式是極爲相似的,總體上,建造者模式僅僅只比工廠模式多了一個“指揮者”的角色。在建造者模式的類圖中,假如把這個指揮者類看做是最終調用的客戶端,那麼圖中剩餘的部分就可以看作是一個簡單的工廠模式了。

與工廠模式相比,建造者模式一般用來創建更爲複雜的對象,因爲對象的創建過程更爲複雜,因此將對象的創建過程獨立出來組成一個新的類——指揮者類。也就是說,工廠模式是將對象的全部創建過程封裝在工廠類中,由工廠類向客戶端提供最終的產品;而建造者模式中,建造者類一般只提供產品類中各個組件的建造,而將具體建造過程交付給指揮者類。由指揮者類負責將各個組件按照特定的規則組建爲產品,然後將組建好的產品交付給客戶端。

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