建造者模式

視頻連接:程序員

 

 

建造者模式ide

建造者模式也是屬於建立型模型,是23種GOF之一。測試

定義:將一個複雜對象的構建和它的表示分離,使一樣的構建構成能夠建立不一樣的表示。ui

建造者模式適用於一個複雜的對象的建造,並且在建造的過程當中,客戶端沒必要知道產品內部組成的細節。this

這裏的表示,咱們用一個具體的例子來講明spa

建造者模式中的角色

建造者(Builder)模式由產品、抽象建造者、具體建造者、指揮者等 4 個要素構成,code

建造者(Builder):爲建立一個產品對象的各個部件指定抽象接口。視頻

具體建造者(ConcreteBuilder):實現Builder的接口以構造和裝配該產品的各個部件,定義並明確它所建立的表示,並提供一個檢索產品的接口。對象

指揮者(Director):指揮並構造一個使用Builder接口的對象。blog

產品(Product):表示被構造的複雜對象。ConcreteBuilder建立該產品的內部表示並定義它的裝配過程,包含定義組成部件的類,包括將這些部件裝配成最終產品的接口。

 

咱們這裏有一需求

需求: 定義一個電腦類,電腦有不少屬性,而且實例化電腦類的對象,以及給該對象賦值。

咱們先不用構造者模式來實現一下

public class Computer{
    private String cpu;
    private String gpu;
    private String memery;
    private String hd;
    /*
     * ................
     * */

    public String getCpu() {
        return cpu;
    }

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

    public String getGpu() {
        return gpu;
    }

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

    public String getMemery() {
        return memery;
    }

    public void setMemery(String memery) {
        this.memery = memery;
    }

    public String getHd() {
        return hd;
    }

    public void setHd(String hd) {
        this.hd = hd;
    }

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

// 測試
public class BuilderTest {
    public static void main(String[] args) {
        Computer computer = new Computer();
        computer.setCpu("i5 9300H");
        computer.setGpu("gtx1650");
        computer.setMemery("16G");
        computer.setHd("256ssd + 1T機械");

        System.out.println(computer);
    }
}

/**
 * 咱們先不用建造者模式,看看會有什麼問題??
 * 1. 客戶端程序,在實例化好產品以後,必須爲該對象的每個屬性賦值,這樣對客戶端程序員來講,太複雜了,須要瞭解compter類的細節
 * 2. 違反了迪米特原則(最少知道原則)
 * 3. 客戶端程序new出來computer對象不能馬上使用,須要設置不少屬性
 *
 * 至關於你去買電腦,商家不是把電腦成品直接給你,而是給你一堆零件,讓你本身組裝
 *
 * 建造者模式與工廠模式的區別:
 * 工廠模式,都是直接實例化出一個類的對象便可。
 * 建造者模式,是在實例化出類的對象以後,還要給該對象每個屬性賦值!
 */

結果

 

 

咱們改進一下代碼

/**
 * 電腦建造者類,建造者類,必須關聯電腦產品
 * 關聯:一個類的對象,做爲另外一個類的對象成員
 */
public class ComputerBuilder {
    private Computer computer = new Computer();

    public Computer build(){
        computer.setCpu("i7 8750HK");
        computer.setGpu("RTX2080");
        computer.setMemery("32G");
        computer.setHd("512ssd + 2T機械");
        return computer;
    }
}

//若是不一樣客戶有不一樣需求呢?

public class V1Test {
    public static void main(String[] args) {
        // 建立一個建造者
        ComputerBuilder computerBuilder = new ComputerBuilder();
        // 玩遊戲
        Computer computer = computerBuilder.build();
        System.out.println(computer);
        // 開發
        Computer computer2 = computerBuilder.build();
        System.out.println(computer2);
        // 辦公
        Computer computer3 = computerBuilder.build();
        System.out.println(computer3);
    }
}

/**
 * 目前這種寫法還不是建造者模式,目前的優勢:
 * 1. 客戶端程序員須要一個產品時,直接向建造者要便可,建造者封裝了電腦建造的複雜過程
 *
 * 目前缺點:
 * 1. 封裝的太過了,不管客戶是什麼需求,都是採用最高的配置
 * 這至關於你去買電腦,無論你是買來幹嗎的,商家都會給你配置最貴的電腦!
 *
 */

結果

 

 這也不符合常理,咱們再改進一下。

建立三個不一樣的建造者

/**
 * 電腦建造者類,建造者類,必須關聯電腦產品
 * 關聯:一個類的對象,做爲另外一個類的對象
 */
public class AdvancedComputerBuilder {
    private Computer computer = new Computer();

    public Computer build(){
        computer.setCpu("i7 8750HK");

        computer.setMemery("32G");
        computer.setHd("512ssd + 2T機械");
        return computer;
    }
}

public class MiddleComputerBuilder {
    private Computer computer = new Computer();

    public Computer build(){
        computer.setCpu("i7 7700hq");
        computer.setGpu("gtx1060");
        computer.setMemery("16G");
        computer.setHd("256ssd + 1T機械");
        return computer;
    }
}

public class LowComputerBuilder {
    private Computer computer = new Computer();

    public Computer build(){
        computer.setCpu("i5 7500u");
        computer.setGpu("gtx940mx");
        computer.setMemery("8G");
        computer.setHd("1T機械");
        return computer;
    }
}

public class V2Test {
    public static void main(String[] args) {
        // 玩遊戲
        AdvancedComputerBuilder advancedComputerBuilder = new AdvancedComputerBuilder();
        Computer computer = advancedComputerBuilder.build();
        System.out.println(computer);
        // 開發
        MiddleComputerBuilder middleComputerBuilder = new MiddleComputerBuilder();
        Computer computer2 = middleComputerBuilder.build();
        System.out.println(computer2);
        // 辦公
        LowComputerBuilder lowComputerBuilder = new LowComputerBuilder();
        Computer computer3 = lowComputerBuilder.build();
        System.out.println(computer3);
    }
}

/**
 *針對不一樣的需求,咱們須要建立不一樣的建造者,來分別生產不一樣配置的產品
 *
 * 這仍不是建造者模式
 * 優勢:
 * 1. 能夠根據客戶端的不一樣需求,使用不一樣的建造者生產產品
 *
 * 缺點:
 * 1. 咱們發現多個建造者中的代碼在重複!出現了重複代碼
 * 2. 建造過程不穩定,如何在某個建造者建立產品的過程當中,漏掉了某一步,編譯器也不會提示。沒有標準
 */

還不行,再改進一下。

咱們將建造電腦的過程抽象出來定義一個接口,之後無論什麼配置的電腦,都是按照這個步驟走,至關於定義了一套規範,將建造過程穩定下來。

public interface ComputerBuilder {
    void setCpu();
    void setGpu();
    void setMemery();
    void setHd();
    Computer build();
}


public class AdvancedComputerBuilder implements ComputerBuilder{
    private Computer computer = new Computer();

    @Override
    public void setCpu() {
        computer.setCpu("i7 8750HK");
    }

    @Override
    public void setGpu() {
        computer.setGpu("RTX2080");
    }

    @Override
    public void setMemery() {
        computer.setMemery("32G");
    }

    @Override
    public void setHd() {
        computer.setHd("512ssd + 2T機械");
    }

    public Computer build(){
        return computer;
    }
}


public class MiddleComputerBuilder implements ComputerBuilder{
    private Computer computer = new Computer();

    @Override
    public void setCpu() {
        computer.setCpu("i7 7700hq");
    }

    @Override
    public void setGpu() {
        computer.setGpu("gtx1060");
    }

    @Override
    public void setMemery() {
        computer.setMemery("16G");
    }

    @Override
    public void setHd() {
        computer.setHd("256ssd + 1T機械");
    }

    public Computer build(){
        return computer;
    }
}


public class LowComputerBuilder implements ComputerBuilder{
    private Computer computer = new Computer();

    @Override
    public void setCpu() {
        computer.setCpu("i5 7500u");
    }

    @Override
    public void setGpu() {
        computer.setGpu("gtx940mx");
    }

    @Override
    public void setMemery() {
        computer.setMemery("8G");
    }

    @Override
    public void setHd() {
        computer.setHd("1T機械");
    }

    public Computer build(){
        return computer;
    }
}
public class V3Test {
    public static void main(String[] args) {
        // 玩遊戲
        AdvancedComputerBuilder advancedComputerBuilder = new AdvancedComputerBuilder();
        advancedComputerBuilder.setCpu();
        advancedComputerBuilder.setGpu();
        advancedComputerBuilder.setMemery();
        advancedComputerBuilder.setHd();
        Computer computer = advancedComputerBuilder.build();
        System.out.println(computer);
        // 開發
        MiddleComputerBuilder middleComputerBuilder = new MiddleComputerBuilder();
        middleComputerBuilder.setCpu();
        middleComputerBuilder.setGpu();
        middleComputerBuilder.setMemery();
        middleComputerBuilder.setHd();
        Computer computer2 = middleComputerBuilder.build();
        System.out.println(computer2);
        // 辦公
        LowComputerBuilder lowComputerBuilder = new LowComputerBuilder();
        lowComputerBuilder.setCpu();
        lowComputerBuilder.setGpu();
        lowComputerBuilder.setMemery();
        lowComputerBuilder.setHd();
        Computer computer3 = lowComputerBuilder.build();
        System.out.println(computer3);
    }
}
/**
 *建立一個建造者的抽象接口,把製做產品的具體步驟穩定下來。
 * 咱們讓建造者類,去實現建造者接口,接口中的方法步驟,類必須都要實現,少一個則會報錯
 *
 * 優勢:
 * 建造者類中的建造過程是穩定的。不會漏掉某一步!!這樣客戶端想擴展建造者時,也不會漏掉某一步
 *
 * 缺點:
 * 1. 代碼依然重複
 * 2. 如今又變成了客戶端本身配電腦,又違反了迪米特法則。
 * (至關於你去買電腦,雖然不用你親自組裝電腦,可是必須「指揮」那個裝機的人,該裝。。該裝什麼。。)
 */
又變成了客戶端本身配電腦,又違反了迪米特法則!!!
下面是咱們真正的建造者模式了
public class Director {
    public Computer build(ComputerBuilder cb){
        cb.setCpu();
        cb.setGpu();
        cb.setMemery();
        cb.setHd();
        return cb.build();
    }
}


public class V4Test {
    public static void main(String[] args) {

        AdvancedComputerBuilder advancedComputerBuilder = new AdvancedComputerBuilder();
        MiddleComputerBuilder middleComputerBuilder = new MiddleComputerBuilder();
        LowComputerBuilder lowComputerBuilder = new LowComputerBuilder();
        Director director = new Director();

        // 玩遊戲
        Computer computer = director.build(advancedComputerBuilder);
        System.out.println(computer);
        // 開發

        Computer computer2 = director.build(middleComputerBuilder);
        System.out.println(computer2);
        // 辦公

        Computer computer3 = director.build(lowComputerBuilder);
        System.out.println(computer3);
    }
}

/**
 *這就是建造者模式
 * 優勢:
 *  1. 建立對象的過程是穩定不變的
 *  2. 建立對象的過程只寫了一次,沒有重複代碼(指揮者完成)
 *  3. 當須要擴展指揮者的時候,不用修改以前的代碼,符合開閉原則
 *
 *
 *  建造者模式與工廠模式的區別
 *  工廠模式只須要一個簡單的new,new出產品便可。
 *  建造者更注重,在new出產品以後的,爲產品賦值的過程!
 */

這就是咱們的建造者模式,顯然它是符合開閉原則的,假如一個客戶須要中高配的電腦,咱們只須要新建一箇中高配電腦的builder,去實現ComputerBuilder接口,再傳入Directer類build就好了,不須要改變以前的代碼。

而一開始說到的表示,就是這這幾個不一樣配置電腦的建造者,LowComputerBuilder,MiddleComputerBuilder和AdvancedComputerBuilder

最後來講下建造者模式與工長模式的區別:

1.工廠模式只須要一個簡單的new,new出產品便可。
2.建造者更注重,在new出產品以後的,爲產品賦值的過程
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息