제이온

[有效 Java] 項目 2. 建構器參數眾多時,考慮使用建構器模式

  • 撰写语言: 韓国語
  • 基准国家: 所有国家country-flag
  • 信息技术

撰写: 2024-04-27

撰写: 2024-04-27 00:46

遞增建構子模式

靜態工廠和建構子在參數眾多時,都難以適當應對。例如,如果類別有 6 個欄位,並且想要在參數為 2 個、3 個…等情況下分別建立建構子,則可以使用以下遞增建構子模式。



但是,即使這樣,如果參數過多,在閱讀程式碼時也可能會混淆每個值的含義,並可能將類型相同的參數混淆並輸入錯誤的值。


Java Bean 模式

Java Bean 模式是使用沒有參數的建構子建立物件,然後呼叫 setter 方法來設定所需參數值的方式。



Java Bean 模式即使參數增加,也能夠避免混淆並建立實體。但是,要建立一個物件,需要呼叫多個 setter 方法,並且在物件完全建立之前,一致性會被破壞。因此,無法使類別成為不可變的。


建構器模式

主要使用兼具遞增建構子模式的穩定性和 Java Bean 模式的可讀性的建構器模式。

用戶端不會直接建立所需的物件,而是呼叫僅包含必需參數的建構子來取得建構器物件。然後,使用建構器物件提供的類似 setter 方法來設定所需的選擇性參數。最後,呼叫沒有參數的 build() 方法來取得所需的物件。



Builder 類別中的建構子只接收必需參數,其餘的選擇性參數則透過類似 setter 方法填入。最後,透過 build() 方法建立完成的 NutritionFactsWithBuilderPattern 物件。NutritionFactsWithBuilderPattern 類別是不可變的,而且建構器的 setter 方法會傳回建構器本身,因此可以連續呼叫。這種方式稱為流暢 API 或方法鏈結。



從用戶端角度來看,透過建構器模式可以輕鬆編寫和閱讀程式碼。


層級設計的類別與建構器模式非常契合


Pizza.Builder 類別是使用遞迴類型限定的泛型類型,並添加了抽象方法 self(),以便子類別在不進行類型轉換的情況下支援方法鏈結。在子類別中,這個抽象方法的傳回值可以是自身。

現在,讓我們看看 Pizza 的子類別紐約披薩和卡爾佐內披薩,體驗建構器模式的靈活性。



每個子類別的建構器定義的 build() 類別都傳回具體的子類別。子類別的方法傳回的類型不是父類別方法傳回的類型,而是其子類型,這項功能稱為協變傳回類型。使用此功能,用戶端無需進行類型轉換。



用戶端可以混合使用 Pizza 的枚舉和每個子類別的枚舉,並透過各自適當的方法完成物件的建立。


建構器模式的缺點

  • 需要建立建構器物件。
  • 程式碼冗長。


總結

如果建構子或靜態工廠方法需要處理大量參數,請考慮使用建構器模式。


參考資料

  • Effective Java

评论0