选择语言
durumis AI 总结的文章
- 如果类在内部依赖于一个或多个资源,则最好不要使用静态实用程序类和单例类,而应该使用依赖注入。
- 使用依赖注入可以提高类的灵活性、可重用性和可测试性,并且可以在构造函数、静态工厂、构建器等中注入资源。
- 依赖注入可以通过传递资源本身或资源工厂来使用,对于依赖关系较多的项目,使用依赖注入框架是高效的。
如果類別內部依賴於一個或多個資源,而這些資源會影響類別的操作,則最好不要使用單例和靜態實用程序類別。
不應讓類別直接創建這些資源,而是應將必要的資源傳遞給構造函數。通過依賴項注入,可以改善類別的靈活性、可重用性和可測試性。
範例
使用靜態實用程序類別的範例
public class SpellChecker {
private static final Lexicon dictionary = new Lexicon();
private SpellChecker() {
}
public static boolean isValid(String word) {
// 使用字典的邏輯
}
public static List suggestions(String typo) {
// 使用字典的邏輯
}
此實用程序類別假設只使用一個字典。但是,在現實世界中,字典可能因語言而異,甚至可能為特殊詞彙單獨使用字典。
使用單例類別的範例
public class SpellChecker {
private final Lexicon dictionary = new Lexicon();
public static SpellChecker INSTANCE = new SpellChecker();
private SpellChecker() {
}
public static boolean isValid(String word) {
// 使用字典的邏輯
}
public static List suggestions(String typo) {
// 使用字典的邏輯
}
單例類別也假設只使用一個字典,因此會出現與上述相同的缺點。
解決方案 1 - 從欄位中移除 final 關鍵字。
public class SpellChecker {
private Lexicon dictionary = new Lexicon();
public static SpellChecker INSTANCE = new SpellChecker();
private SpellChecker() {
}
public static void changeDictionary(Lexicon dictionary) {
this.dictionary = dictionary;
}
public static boolean isValid(String word) {
// 使用字典的邏輯
}
public static List suggestions(String typo) {
// 使用字典的邏輯
}
可以從靜態實用程序類別或單例類別的字典中移除 final 關鍵字,並設計允許從外部替換字典的機制。但是,這種方法本身難以使用,並且在多線程環境中可能會導致同步問題。
解決方案 2 - 使用依賴項注入。
public class SpellChecker {
private final Lexicon dictionary;
public SpellChecker(Lexicon dictionary) {
this.dictionary = dictionary;
}
public static boolean isValid(String word) {
// 使用字典的邏輯
}
public static List suggestions(String typo) {
// 使用字典的邏輯
}
通過上述範例,可以感受到靜態類別和單例類別不應該依賴於內部資源。也就是說,最好將內部資源從外部注入。
使用依賴項注入的類別得益於 final 關鍵字,可以保證不變性,並且支持多個資源實例。此外,依賴項注入不僅可以在構造函數中使用,還可以在靜態工廠和構建器中使用。
依賴項注入不僅可以簡單地傳遞資源本身,而且通常也使用傳遞資源工廠的方式。工廠是指在調用時重複創建特定類型實例的對象。這種方法稱為工廠方法模式,Java 8 中的 Supplier
public static List create(Supplier extends Car> generator) {
...
通常使用受限通配符類型來限制工廠的類型參數。使用這種方法,客戶端可以傳遞任何與其指定類型兼容的子類型作為工廠。
依賴項注入雖然可以提高靈活性並簡化測試,但在依賴關係過多的項目中,成本可能會非常高。在這種情況下,可以使用依賴項注入框架(如 Dagger、Guice、Spring 等)來降低成本。