1. 程式人生 > >23種設計模式之建造者模式

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

建造者模式的定義

建造者模式也叫生成器模式, 定義如下:

將一個複雜物件的構建與它的表示分離, 使得同樣的構建過程可以建立不同的表示

類圖如下:

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

 

在建造者模式中, 四個角色如下:

  1. Product 產品類: 通常是實現了模板方法模式, 也就是有模板方法和基本方法
  2. Builder 抽象建造者: 規範產品的組建, 一般是由子類實現
  3. ConcreteBuilder 具體建造者: 實現抽象類定義的所有方法,並且返回一個組建好的物件.
  4. Director 導演類: 負責安排已有模組的順序, 然後告訴Builder開始建造.

先看Product類的程式碼, 通常他是一個組合或繼承產生的類:

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

 

抽象建造者程式碼如下:

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

 

其中 setPart 方法是零件的配置, 其他的物件, 獲得一個不同零件,或者不同的裝配順序就可能產生不同的產品

具體建造者程式碼如下:

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

 

導演類程式碼:

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

 

導演類起到封裝的作用,避免高層模組深入到建造者內部的實現類. 當然, 在建造者模式比較龐大時, 導演類可以有多個

建造者模式分析

現在又一個專案,建立不同的汽車, 有賓士的寶馬的, 車有啟動、停止、喇叭聲音、引擎聲音, 不同車有不同的順序, 開始建立, 先使用模板方法模式, 類圖如下

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

 

在CarModel中定義了一個 setSequence 方法, 車輛模型的這幾個動作要如何排布, 是在 ArrayList中定義的. 然後run方法根據 sequence定義的順序完成指定的順序動作

CarModel程式碼:

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

 

CarModel是這樣設計的, setSequence方法允許客戶自己設定一個順序, 是先啟動還是先按喇叭, 在子類中實現其基本方法, 然後同過run方法實現順序呼叫

其實現類程式碼就不再佔用篇幅

這時有一個要求, 生產一個賓士模型,要先發動引擎,再啟動,然後停下來,不需要按喇叭, 建立程式碼如下:

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

 

這樣我們就建立了一輛汽車, 但是需求是汽車的執行順序要能夠隨意調整, 我們只滿足了一個, 還有下一個,下下個, 那怎麼辦? 我們每次都要寫這些來滿足. 我們要想辦法解決這個問題, 那麼我們可以通過建造者, 通過建造者建立, 類圖如下

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

 

其 CarBuilder 程式碼如下:

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

 

實現類程式碼如下

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

 

這樣,我們就可以通過一個導演類,封裝各個順序並返回產品

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

 

其中的方法可以新增,可以有很多方法

這樣,再建立的時候就輕鬆多了,直接呼叫一個方法即可

這不是一個單純的建造者模式, 其中使用了模板方法模式

建造者模式的應用

優點如下:

  1. 封裝性. 使用建造者模式可以是客戶端不必知道產品內部組成的細節
  2. 建造者獨立, 容易擴充套件
  3. 便於控制細節風險. 由於具體的建造者是獨立的, 因此可以對建造過程逐步細化, 而不對其他的模組產生任何影響

建造者模式的使用場景:

  1. 相同的方法,不同的執行順序,產生不同的事件結果時,可以採用建造者模式
  2. 多個部件或零件,都可以裝配到一個物件中,但是產生的執行結果又不相同時,則可以使用
  3. 產品非常複雜,或者產品類中的呼叫順序不同產生了不同的效能,這個時候使用建造者模式非常合適
  4. 在物件建立過程中也會使用到系統中的一些其他物件,這些物件在產品物件的建立過程中不易得到時,也可以採用建造者模式封裝該物件的建立過程.這種場景只能是一個補償方法, 因為一個物件不容易獲得, 而在設計 階段竟然沒有發覺, 而要通過建造者模式柔化建立過程,本身已經違反設計的最初目標

建造者模式關注的是零件型別和裝配工藝(順序), 這是它與工廠方法模式最大不同的地方, 雖然同為建立類模式, 但是注重點不同


建造者模式最主要的功能是基本方法的呼叫順序安排,而工廠方法則重點是建立


 

 

可以關注一下鄙人的公眾號, 謝謝各位了!