在Java中創建實用程序(不包含任何狀態)類的最佳實踐是什麼?在Java中創建無狀態實用程序類的最佳實踐是什麼
在大多數情況下,我們最終都會爲這些任務創建靜態方法。 其他可能的方式可能是「創建單體對象」來執行此操作。
當需求是代碼時應該怎麼設計考慮應該很容易單元測試?
在Java中創建實用程序(不包含任何狀態)類的最佳實踐是什麼?在Java中創建無狀態實用程序類的最佳實踐是什麼
在大多數情況下,我們最終都會爲這些任務創建靜態方法。 其他可能的方式可能是「創建單體對象」來執行此操作。
當需求是代碼時應該怎麼設計考慮應該很容易單元測試?
我認爲最常見的方法是創建靜態方法。舉例來說,參見StringUtils in Apache Commons Lang,Strings in Guava或甚至Arrays in JDK。
此外,該類應該是最終的,它應該有一個私有構造函數,以避免繼承或實例化它。
要麼你使用靜態方法或單例,它應該是相同的努力,單元測試它。在後一種情況下,你可能會寫更多的代碼(字符)。
我知道面向對象的純粹主義者會爭論這些類的存在,我會傾向於同意他們,但這些僅僅是爲了簡單起見而添加的,您應該限制這些類的數量。
如果您使用Spring之類的框架,您可以使用@Service
註釋創建一個實用程序類。 這將確保它是單一實例(SIngleton),並且可以簡單地將它注入到任何其他需要使用其方法的類中。
在任何其他情況下,我建議使用工廠模式或cotrast使用靜態方法使其成爲單例。
Static是單身人士。使用非靜態方法的單例實例只有在需要使用不同屬性(多個)/設置(多個)值的多個Utility類變體時才需要。例如,當您的實用程序具有某些屬性(即customProperty)並且您同時需要兩個不同的案例時。
工具時需要使用CustomProperty的=值
時Utitlity需要使用CustomProperty的=數值...
,但它是很奇怪的,笨拙,也不好..實用程序調用者可以將所需的屬性值提供給靜態方法。所以,不要因此而陷入困境。 make實用方法總是靜態的,不關心的「理論」模式... :)
如果你滿足我的比喻有點...
你可能已經看到這些人之前:
請注意,我們稱之爲烤麪包機。我們做而不是稱之爲「BreadUtil」。
同樣,實用方法可以也應該放在一個名爲特定功能的類中,而不是「與麪包相關的雜項。「
大多數情況下,您的靜態方法屬於相關的類;例如,Integer.parseInt是Integer類的靜態方法,不是理論IntegerUtil或NumberUtil類的成員。
過去,創建單獨的工具類的一種情況是當主要類感興趣的是接口。一個例子是java.util.Collections。但是,從Java 8開始,這不是一個藉口,因爲接口可以有靜態方法和默認方法。實際上,Collections.sort(List)已經被遷移到List.sort。
如果您有很多實用方法,並且您覺得他們會混淆相關類,可以將它們放在單獨的類中,但不是「BreadUtil」類。在類名(或「utils」,「utilities」,「misc」,「miscellaneous」,「general」,「shared」,「common」或「framework」)中放置「util」這個詞是不可接受的。 。給班級一個有意義的名字,描述這些方法的用途。如果方法太多而不能容許這樣的類名,那麼你可能需要將它們分成多個類。 (只有很少幾種方法的小班是完全可以接受的;許多人甚至認爲這是一個好的設計。)
回到整數示例,如果您覺得方法混淆了類,則可以創建如下這樣的新類:
public class IntegerMath {
private IntegerMath() { }
public static int compare(int x, int y) { /* ... */ }
public static int compareUnsigned(int x, int y) { /* ... */ }
public static int divideUnsigned(int dividend, int divisor) { /* ... */ }
public static int min(int a, int b) { /* ... */ }
public static int max(int a, int b) { /* ... */ }
public static int remainderUnsigned(int dividend, int divisor) { /* ... */ }
public static int signum(int i) { /* ... */ }
public static int sum(int a, int b) { /* ... */ }
public static long toUnsignedLong(int i) { /* ... */ }
}
public class IntegerBits {
private IntegerBits() { }
public static int bitCount(int i) { /* ... */ }
public static int highestOneBit(int i) { /* ... */ }
public static int lowestOneBit(int i) { /* ... */ }
public static int numberOfLeadingZeros(int i) { /* ... */ }
public static int numberOfTrailingZeros(int i) { /* ... */ }
public static int reverse(int i) { /* ... */ }
public static int reverseBytes(int i) { /* ... */ }
public static int rotateLeft(int i, int distance) { /* ... */ }
public static int rotateRight(int i, int distance) { /* ... */ }
}
public class IntegerParser {
private IntegerParser() { }
public static int parseInt(String s) { /* ... */ }
public static int parseInt(String s, int radix) { /* ... */ }
public static int parseUnsignedInt(String s) { /* ... */ }
public static int parseUnsignedInt(String s, int radix) { /* ... */ }
}
最後的是,可能是沒有靜態方法更好的東西的例子:
public class IntegerParser {
public IntegerParser() { this(10); }
public IntegerParser(int radix) { /* ... */ }
public int parseInt(String s) { /* ... */ }
public int parseUnsignedInt(String s) { /* ... */ }
}
什麼是用於創建實用的最佳實踐(不HOL d任何狀態)在Java中的類。
在我看來,最好的方法是儘可能省略實用程序類。
實用類反轉了面向對象編程的思想。當你發現你需要一種新方法時,你通常會把它添加到具有最高凝聚力的課堂上。這意味着需要掌握方法所需信息的類。其他信息將作爲參數傳遞給方法。如果參數列表太長,通常是錯誤放置方法的指標。
當您確實需要實用程序類來爲某種類型提供方法時,存在少數情況。例如。
在大多數的我們最終創造了這樣的任務靜態方法的情況下。其他可能的方式可能是「創建單個對象」來執行此操作。
當需求是代碼時應該怎麼設計考慮應該很容易單元測試?
如果您從單元測試性的角度來看實用程序類,並且希望能夠模擬實用程序類,則應該使用單例,因爲可以替換對象引用。
通過改變單例實例引用(靜態變量)或通過使用對象字段在客戶端。例如。
private SomeUtility someUtility = SomeUtiltiy.INSTANCE;
public void someMethod(...){
// Can be replaced by changing the someUtility reference
someUtility.doSomething(....);
// A static call like
// SomeUtility.doSomething(...);
// can not be easily replaced.
}
靜態方法調用很難替換。通過重寫客戶端字節碼,一些測試框架如powermock
支持mocking of static calls。但我認爲這些框架旨在支持糟糕的遺留代碼的單元測試。如果你需要新代碼的powermock,你應該重新考慮你的設計。
如果您創建通用字符串或數組操作的庫,該怎麼辦?這通常是公用事業類的目的。簡單類型或對象的基元(或不那麼原始)操作。 –
無論何時您看到Java或任何OO語言的實用程序類,都可能表示某些內容已丟失。也就是說,你的模型中有一些對象需要存在。這是一個考慮可能的機會,所以您可以使您的系統更具可測試性和靈活性。 –