23種設計模式之建造者模式

一、定義

將一個複雜對象的構造與它的表示分離,使一樣的構建過程能夠建立不一樣的表示。建造者模式是將一個複雜的對象分解爲多個簡單的對象,而後一步一步構建而成。它將變與不變相分離,即產品的組成部分是不變的,但每一部分是能夠靈活選擇的。編程

二、模式結構

構造者模式由四部分組成:bash

  • 抽象構造者(Builder)角色:給出一個抽象接口,以規範產品對象的各個組成成分的建造。通常而言,此接口獨立於應用程序的商業邏輯。模式中直接建立產品對象的是具體建造者角色。具體建造者類必須實現這個接口所要求的兩個方法:一種是建造方法,另外一種是返回結構方法。通常來講,產品所包含的零件數目與建造方法的數目相符。換言之,有多少零件,就有多個相應的建造方法。
  • 具體構造者(ConcreteBuilder)角色:與應用程序緊密相關的一些類,它們在應用程序調用下建立產品的實例。這個角色要完成的任務包括:實現抽象創造者所聲明的接口,給出一步一步地完成建立產品實例的操做;在建造過程完成後,提供產品的實例。
  • 導演者(Director)角色:負責調用具體建造者按照順序建造產品。導演者只負責調度,真正執行的是具體建造者角色。
  • 產品(Product)角色:產品即是建造中的複雜對象。

三、實例

3.1 房子(產品類)app

public class House {
    private String basis;
    private String wall;
    private String roof;
    
    // toString、getter方法和setter方法
}
複製代碼

3.2 抽象構造者類ide

public abstract class HouseBuilder {
    public abstract void buildBasis();
    public abstract void buildWall();
    public abstract void buildRoof();
    public abstract House getHouse();
}
複製代碼

3.3 具體構造者類ui

public class HighBuilding extends HouseBuilder{
     private House house = new House();
     
     @Override
     public void buildBasic() {
         house.setBasic("高樓打地基100m深");
     }
     
     @Override
     public void buildWall() {
         house.setWall("高樓砌牆30cm寬");
     }
     
     @Override
     public void buildRoof() {
         house.setRoof("高樓使用透明屋頂");
     }
     
     @Override
     public House getHouse(){
         return house;
     }
}
複製代碼

3.4 導演者類spa

public class HouseDirector {
    
    public void buildHouse(HouseBuilder houseBuilder) {
        houseBuilder.buildBasis();
        houseBuilder.buildWall();
        houseBuilder.buildRoof();
    }
}
複製代碼

3.5 客戶端調用code

public class Test {
    public static void main(String[] args) {
        HouseBuilder highBuilding = new HighBuilding();
        HouseDirector houseDirector = new HouseDirector();
        houseDirector.buildHouse(highBuilding);
        System.out.println(highBuilding.getHouse().toString());
    }
}
複製代碼

四、適用場景

  • 須要生成的產品對象有複雜的內部結構,這些產品對象一般包含多個成員屬性。
  • 須要生成的產品對象的屬性相互依賴,須要指定其生成順序。
  • 對象的建立過程獨立於建立該對象的類。在建造者模式中引入了指揮者類,將建立過程封裝在指揮着類,而不在建造類中。
  • 隔離複雜對象的建立和使用,並使得相同的建立過程能夠建立不一樣的產品。

五、在JDK的應用

StringBuilder的部分源碼:cdn

  • Appendable接口定義了多個append方法(抽象方法),即Appendable爲抽象建造者。
  • AbstractStringBuilder實現了Appendable接口方法,這裏的AbstractStringBuilder已是建造者,只是不能實例化。
  • StringBuilder即充當了指揮者角色,同時充當了具體的建造者,建造方法的實現是由AbstractStringBuilder完成,而StringBuilder繼承了AbstractStringBuilder.

六、優缺點

6.1 優勢
  • 客戶端(應用程序)沒必要知道產品內部組成的細節,將產品自己與產品的建立過程解耦,使得相同的建立過程能夠建立不一樣的產品對象。
  • 每個具體建造者都相對獨立,而與其餘的具體建造者無關,所以能夠很方便地替換具體建造者或增長新的具體建造者,用戶使用不一樣的具體建造者便可獲得不一樣的產品對象。
  • 能夠更加精細地控制產品的建立過程。將複雜產品的建立步驟分解在不一樣的方法中,使得建立過程更加清晰,也更方便使用程序來控制建立過程。 *增長新的具體建造者無須修改原有類庫的代碼,指揮者類針對抽象建造者類編程,系統擴展方便,符合「開閉原則」。
6.2 缺點
  • 建造者模式所建立的產品通常具備較多的共同點,其組成部分類似,若是產品之間的差別性很大,則不適合使用建造者模式,所以使用範圍受到必定的限制。
  • 若是產品的內部變化複雜,可能會致使須要定義很大具體建造者類來實現這種變化,致使系統變得很龐大,所以在這種狀況下,要考慮是否選擇建造者模式。

七、建造者模式和抽象工廠的區別

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

特別聲明:一、如若文中有錯之處,歡迎大神指出。 二、文章是參考網上一些大神的文章,本身整理出來的,如如有侵權,可聯繫我刪除。 對象

相關文章
相關標籤/搜索