設計模式之建造者模式

定義

將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不用的表示。

用戶只需指定需要建造的類型就可以得到它們,建造過程及細節不需要知道。

類型

創建型

適用場景

①、如果一個對象有非常複雜的內部結構(很多屬性)
②、想把複雜對象的創建和使用分離。

優缺點

優點:
①、封裝性好,創建和使用分離。
②、擴展性好、建造類之間獨立、一定程度上解耦。

缺點:
①、產生多餘的Builder對象。
②、產品內部發生變化,建造者都要修改,成本較大。

代碼實現

案例:組裝一臺電腦,需要顯示器、鼠標、鍵盤、CPU、內存條等等。
這裏直接創建一個電腦類。

public class Computer {

    /**
     * 顯示器
     */
    private String computerDisplay;

    /**
     * 鼠標
     */
    private String computerMouse;

    /**
     * 鍵盤
     */
    private String computerKeyBoard;

    /**
     * CPU
     */
    private String computerCPU;

    /**
     * 電源
     */
    private String computerSource;

    public Computer(ComputerBuilder computerBuilder) {
        this.computerDisplay = computerBuilder.computerDisplay;
        this.computerMouse = computerBuilder.computerMouse;
        this.computerKeyBoard = computerBuilder.computerKeyBoard;
        this.computerCPU = computerBuilder.computerCPU;
        this.computerSource = computerBuilder.computerSource;
    }

    @Override
    public String toString() {
        return "Computer{" +
                "computerDisplay='" + computerDisplay + '\'' +
                ", computerMouse='" + computerMouse + '\'' +
                ", computerKeyBoard='" + computerKeyBoard + '\'' +
                ", computerCPU='" + computerCPU + '\'' +
                ", computerSource='" + computerSource + '\'' +
                '}';
    }

    /**
     * 靜態內部類(建造者)
     */
    public static class ComputerBuilder {
        private String computerDisplay;

        private String computerMouse;

        private String computerKeyBoard;

        private String computerCPU;

        private String computerSource;

        public ComputerBuilder builderComputerDisplay(String computerDisplay) {
            this.computerDisplay = computerDisplay;
            return this;
        }

        public ComputerBuilder builderComputerMouse(String computerMouse) {
            this.computerMouse = computerMouse;
            return this;
        }

        public ComputerBuilder builderComputerKeyBoard(String computerKeyBoard) {
            this.computerKeyBoard = computerKeyBoard;
            return this;
        }

        public ComputerBuilder builderComputerCPU(String computerCPU) {
            this.computerCPU = computerCPU;
            return this;
        }

        public ComputerBuilder builderComputerSource(String computerSource) {
            this.computerSource = computerSource;
            return this;
        }

        /**
         * 將當前建造者傳入
         */
        public Computer builder() {
            return new Computer(this);
        }
    }

這裏使用了靜態內部類,採用鏈式調用,返回建造者本身。最後寫一個測試方法。

    @Test
    public void test1() {
        Computer computer = new Computer.ComputerBuilder()
                .builderComputerDisplay("LG")
                .builderComputerMouse("牧馬人")
                .builderComputerKeyBoard("羅技")
                .builderComputerCPU("酷睿i7")
                .builderComputerSource("電源")
                .builder();
        System.out.println(computer);
    }

看測試結果

C:\android\java\jdk1.8\bin\java.exe

Computer{computerDisplay='LG', computerMouse='牧馬人', computerKeyBoard='羅技', computerCPU='酷睿i7', computerSource='電源'}

當然,這裏是按需調用,調用完之後可以鏈式調用。假如我不想買鼠標了,就不用調用builderComputerMouse()這個方法了,或者我只想買一個顯示器,只用調用builderComputerDisplay()這一個方法即可。

相關源碼

1. StringBuilder、StringBuffer中的append
2. guava中的ImmutableSet中的add
3. CacheBuilder
4. Spring中的BeanDefinitionBuilder
5. SqlSessionFactoryBuilder

注意事項

建造者模式和工廠模式比較相近。
①、調用順序。建造者模式更注重於方法的調用順序,而工廠模式注重於創建產品。
②、創建對象的粒度不同。建造者模式可以創建一些複雜的產品,而工廠模式創建出來的都是一樣的產品。
③、關注點不一樣。工廠模式只要把這個對象創建就OK了,而建造者模式不僅要創建這個產品,還要知道這個產品是由哪些部件組成的。

參考鏈接
https://coding.imooc.com/learn/list/270.html

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