Yog*_*esh 17 java design-patterns
在Java中创建实用程序(不包含任何状态)类的最佳实践是什么.
在大多数情况下,我们最终会为此类任务创建静态方法.其他可能的方法可能是"创建单例对象"以执行此操作.
当需求是代码时应该设计考虑的应该是容易单元测试的?
VGR*_*VGR 33
如果你稍稍放纵一下我的比喻......
您之前可能已经看过其中一个:
![]()
请注意,我们称之为烤面包机.我们不称它为"BreadUtil".
类似地,实用程序方法可以而且应该放在以特定功能命名的类中,而不是"与面包相关的杂项内容".
大多数情况下,您的静态方法属于相关类; 例如,Integer.parseInt是Integer类的静态方法,不是理论上的IntegerUtil或NumberUtil类的成员.
在过去,创建单独的实用程序类的一种情况是当感兴趣的主要类是接口时.一个例子是java.util.Collections.但是,从Java 8开始,这不是一个借口,因为接口可以有静态方法和默认方法.实际上,Collections.sort(List)已经迁移到List.sort.
如果你有很多实用方法,并且你觉得它们会混淆相关的类,可以将它们放在一个单独的类中,但不能放在"BreadUtil"类中.将"util"放在类名(或"utils","utilities","misc","miscellaneous","general","shared","common"或"framework")中是绝对不可接受的. .为类提供一个有意义的名称,用于描述方法的用途.如果方法太多而不允许这样的类名,则可能需要将它们拆分为多个类.(只有少数方法的小班是完全可以接受的;许多人甚至认为这是一个好的设计.)
回到Integer示例,如果您觉得方法混乱了类,您可以创建这样的新类:
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) { /* ... */ }
}
Run Code Online (Sandbox Code Playgroud)
最后一个是没有静态方法可能更好的例子:
public class IntegerParser {
public IntegerParser() { this(10); }
public IntegerParser(int radix) { /* ... */ }
public int parseInt(String s) { /* ... */ }
public int parseUnsignedInt(String s) { /* ... */ }
}
Run Code Online (Sandbox Code Playgroud)
我认为最常见的方法是创建静态方法。举个例子看到了Apache Commons Lang中StringUtils的,番石榴字符串,甚至在JDK阵列。
同样,该类应设为final,并且应具有私有构造函数,以避免继承或实例化该类。
无论您使用静态方法还是单例,都应该对单元测试进行相同的工作。在后一种情况下,您可能需要编写更多代码(字符)。
我知道面向对象的纯粹主义者会争辩此类类的存在,我倾向于同意它们,但是添加这些类只是为了简单起见,您应该限制此类的数量。