1. 程式人生 > 實用技巧 >Echarts實現地圖下鑽+對應區域資料展示+右鍵返回上一級

Echarts實現地圖下鑽+對應區域資料展示+右鍵返回上一級

建造者模式

建造者模式Builder Pattern又可以稱為生成器模式,是將一個複雜物件的構建與它的表示分離,使得同樣的構建過程可以建立不同的表示,建造者模式屬於物件建立型模式。

描述

建造者模式是一步一步建立一個複雜的物件,它允許使用者只通過指定複雜物件的型別和內容就可以構建它們,使用者不需要知道內部的具體構建細節。

模式結構

  • Builder: 抽象建造者,引入抽象建造者的目的,是將建造的具體過程交與它的子類來實現。這樣更容易擴充套件。一般至少會有兩個抽象方法,一個用來建造產品,一個是用來返回產品。
  • ConcreteBuilder: 具體建造者,實現抽象類的所有未實現的方法,具體來說一般是兩項任務:組建產品、返回組建好的產品。
  • Director: 指揮者,負責呼叫適當的建造者來組建產品,指揮者一般不與產品類發生依賴關係,與指揮者直接互動的是建造者類,一般來說指揮者被用來封裝程式中易變的部分。
  • Product: 產品角色,一般是一個較為複雜的物件,產品類可以是由一個抽象類與它的不同實現組成,也可以是由多個抽象類與他們的實現組成。

比較

  • 與抽象工廠模式相比,建造者模式返回一個組裝好的完整產品,而抽象工廠模式返回一系列相關的產品,這些產品位於不同的產品等級結構,構成了一個產品族。
  • 在抽象工廠模式中,客戶端例項化工廠類,然後呼叫工廠方法獲取所需產品物件,而在建造者模式中,客戶端可以不直接呼叫建造者的相關方法,而是通過指揮者類來指導如何生成物件,包括物件的組裝過程和建造步驟,它側重於一步步構造一個複雜物件,返回一個完整的物件。
  • 如果將抽象工廠模式看成汽車配件生產工廠,生產一個產品族的產品,那麼建造者模式就是一個汽車組裝工廠 ,通過對部件的組裝可以返回一輛完整的汽車。

優點

  • 在建造者模式中, 客戶端不必知道產品內部組成的細節,將產品本身與產品的建立過程解耦,使得相同的建立過程可以建立不同的產品物件。
  • 每一個具體建造者都相對獨立,而與其他的具體建造者無關,因此可以很方便地替換具體建造者或增加新的具體建造者, 使用者使用不同的具體建造者即可得到不同的產品物件 。
  • 可以更加精細地控制產品的建立過程,將複雜產品的建立步驟分解在不同的方法中,使得建立過程更加清晰,也更方便使用程式來控制建立過程。
  • 增加新的具體建造者無須修改原有類庫的程式碼,指揮者類針對抽象建造者類程式設計,系統擴充套件方便,符合開閉原則。

缺點

  • 建造者模式所建立的產品一般具有較多的共同點,其組成部分相似,如果產品之間的差異性很大,則不適合使用建造者模式,因此其使用範圍受到一定的限制。
  • 如果產品的內部變化複雜,可能會導致需要定義很多具體建造者類來實現這種變化,導致系統變得很龐大。

實現

class Product{ // 具體產品
    constructor(){
        this.name = null;
        this.type = null;
    }
    setName(name){
        this.name = name;
    }
    setType(type){
        this.type = type;
    }
    showProduct(){
        console.log("name:", this.name);
        console.log("type:", this.type);
    }
}

class Builder{ // 抽象建造者
    setPart(name, type){
        throw new Error("Abstract method cannot be called");
    }
    getProduct(){
        throw new Error("Abstract method cannot be called");
    }
}

class ConcreteBuilder extends Builder{ // 實體建造者
    constructor(){
        super();
        this.product = new Product();
    }
    build(name, type){
        this.product.setName(name);
        this.product.setType(type);
    }
    getProduct(){
        return this.product;
    }
}

class Director{ // 指揮者
    constructor(){
        this.builder = new ConcreteBuilder();
    }
    getProductA(){
        this.builder.build("A", "TypeA");
        return this.builder.getProduct();
    }

    getProductB(){
        this.builder.build("B", "TypeB");
        return this.builder.getProduct();
    }
}

(function() {
    var director = new Director();
    var productA = director.getProductA();
    productA.showProduct(); // name: A type: TypeA
    var director = new Director();
    var productB = director.getProductB();
    productB.showProduct(); // name: B type: TypeB
})()

每日一題

https://github.com/WindrunnerMax/EveryDay

參考

https://www.runoob.com/design-pattern/builder-pattern.html
https://wiki.jikexueyuan.com/project/java-design-pattern/builder-pattern.html
https://design-patterns.readthedocs.io/zh_CN/latest/creational_patterns/builder.html