如果類別在內部依賴一個或多個資源,並且這些資源會影響類別的行為,則不建議使用單例和靜態工具類。
類別不應該自行建立這些資源,而是應該將所需的資源傳遞給建構函式。透過依賴注入,可以改進類別的彈性、可重複使用性和可測試性。
範例
使用靜態工具類的範例
此工具類假設只使用一個字典。但在現實情況中,字典可能是按語言分開的,甚至可能為特殊詞彙設置單獨的字典。
使用單例類別的範例
單例類別也假設只使用一個字典,因此存在與上述相同的缺點。
解決方案 1 - 從欄位中移除 final 關鍵字
也可以從靜態工具類或單例類別的 dictionary 中移除 final 關鍵字,並允許從外部將 dictionary 替換為其他字典。但是,這種方法本身使用起來很笨拙,並且在多執行緒環境中可能會導致併發問題。
解決方案 2 - 使用依賴注入
透過上述範例,可以了解到靜態類別和單例類別不應該依賴內部資源。也就是說,最好將內部資源從外部注入。
使用依賴注入的類別可以透過 final 關鍵字保證不變性,並且支援多個資源實例。此外,依賴注入不僅可以在建構函式中使用,還可以在靜態工廠和建構器中使用。
依賴注入不僅可以簡單地傳遞資源本身,還可以傳遞資源工廠。工廠是指每次呼叫時都會重複建立特定類型實例的物件。這種方法稱為工廠方法模式,Java 8 中的 Supplier<T> 就是表達工廠的完美範例。
通常使用限定型別通配符來限制工廠的類型參數。使用這種方法,客戶端可以將任何其指定類型的子類型傳遞給工廠。
依賴注入可以改進彈性和可測試性,但在依賴關係非常多的專案中,成本可能相當高。在這種情況下,可以使用依賴注入框架(例如 Dagger、Guice 和 Spring)來降低成本。
评论0