大白話建造者模式(Builder Pattern)


前言

起初打算按照之前的日產系列寫建造者模式。但參考了網上的很多文章,讓我對建造者模式更加的困惑,也害怕自己無法已易懂的方式進行解釋。最后通過Google發現了一篇英文文章Builder,使我茅塞頓開。我自己對這篇文章進行了翻譯,希望對大家理解建造者模式有幫助。

意圖

建造者模式是創建型設計模式,用來逐步創建復雜的對象。使用建造者模式可以使用相同的構造代碼生成不同類型、不同表示的對象。

問題

想象一個復雜的對象,它需要大量字段和嵌套對象進行初始化。這種的初始化代碼一般會隱藏在一個包含大量參數的龐大構造函數中。
為對象的每一種可能創建子類,會使程序過於復雜。

比如,我們來建一個房子對象。建造一個簡單的房子需要四面牆、一層地板、一扇門、一對窗戶和一個屋頂。但是如果我們想要一個更大更明亮,並且有后院和其他好東西(比如暖氣系統、管道和電線)的房子,那該怎么辦呢?

最簡單的解決方案是繼承基本House類並創建一組子類來覆蓋所有參數組合,但是后得到大量的子類。任何新的參數都需要進一步擴展這個層次結構。

另一個方法不用派生子類。你可以創建一個包含所有參數的構造函數。這種方法不需要大量的子類,但是存在另外的問題。
大量參數的構造函數也存在問題,並非所有參數都是被需要的
在大多數情況下,大部分的參數是不被使用的。這樣調用構造函數時會顯得代碼十分難看。

解決

建造模式建議您從自己的類中提取對象構造代碼,將其移動到被稱為生成器的獨立對象中。
建造者模式允許您逐步構造復雜的對象。構建器在構建產品時不允許其他對象訪問該產品。

建造者模式將對象構造組織為一組步驟(建牆、建門等)。在Builder對象上執行一系列步驟就可以創建一個對象。最重要的一點是,您無需調用所有的步驟,需要調用需要的步驟即可。

當需要構建產品的各種表現形式時,某些步驟可能需要不同的實現。比如,小屋的牆壁可以用木頭建造,但城堡的牆壁需要用石頭建造。
這種場景下,可以創建不同的建造者類來實現相同的建造步驟,不同的類型。接下來就可以使用這些建造不同類型的對象。

不同的建造者以不同的方式執行相同的任務,生成不同的

例如,第一個建造者用木頭和玻璃建造一切,第二個用石頭和鐵建造一切,第三個用黃金和鑽石建造一切。通過調用相同的步驟,你可以從第一個建造者那里得到一個普通的房子,從第二個建造者那里得到一個小城堡,從第三個建造者那里得到一個宮殿。

Director

我們可以進一步的將一系列對建造者步驟的調用提取到一個類中,這個類被稱為Director。
Director類只定義了執行構建步驟的順序,而構建器提供了這些步驟的實現。
Director知道執行哪些構建步驟來獲得產品
Direct類不是絕對必要的,我們可以按照特定的順序直接調用Builder。但是,Director是放置各種可重用構造方案的好方法。
另外,Director類完全隱藏了產品構造的細節。客戶端只需要將一個Builder和一個Director關聯起來就可以得到構建結果。

結構

  1. Builder接口聲明了對所有類型的生成器都通用的產品構造步驟。
  2. Concrete Builders 提供了
    構建步驟的不同實現。
  3. Products是需要產生的對象。不同構造器構建的產品可以屬於不同的類層級結構(繼承)或者接口。
  4. Director類定義了調用構造步驟的順序,因此您可以創建和重用產品的特定構造方式。
  5. Client必須將一個Builder對象與Director關聯起來。通常,通過director的構造函數的參數只執行一次。然后,director將該Builder對象用於所有的構造。還有一種方式是將Builder對象傳遞給Director的方法,可以使用不同的生成器。

場景

  • 建造者模式用來拜托過長的構造函數。
  • 創建某些產品的不同表示形式,比如石房和木房。
  • 構造復雜對象,將構造代碼和業務代碼分離。

代碼

代碼我沒有粘過來,直接訪問參考文獻里的底部即可。

參考文獻

https://refactoring.guru/design-patterns/builder


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM