如果我必须设计一个Utility类(例如ByteUtils或StreamUtils或StringUtils),那么它们的最佳设计选择是什么。
PS:通过静态类,我的意思是一个带有静态方法的类(而不是内部静态类)
请为此提供有关设计选择的建议?
答案 0 :(得分:61)
我的实用程序类看起来像这样:
// final, because it's not supposed to be subclassed
public final class FooUtil {
// private constructor to avoid unnecessary instantiation of the class
private FooUtil() {
}
public static int doSomethingUseful() {
}
// ...
}
请注意,尽管这使得实用程序方法易于测试,并且可以从外部轻松访问,但它也使得使用它们的类很难进行单元测试,因为模拟这些实用程序方法并不容易。拥有太多这样的实用程序类可能是缺乏OO设计(程序编程)的标志,并且可以使代码难以测试。
如果您正在使用依赖注入框架(Spring,Guice,无论如何),那么使用非静态方法使实用程序类可实例化,并使其成为可注入的单例可能是个好主意。这样,可以通过模拟实用程序对象来测试使用这些实用程序方法的类。
答案 1 :(得分:41)
如果它是通用实用程序,则静态是IMO更好。你声明你不会有任何州存储,所以我不明白你为什么要把它作为非静态的。声明它是静态的也会节省内存。
答案 2 :(得分:22)
仅仅因为某些东西可能是静态的,并不意味着它应该是静态的。
还有另一个考虑因素:嘲笑。在测试中模拟静态方法比模拟类实例的行为更难。
谈论不必要的堆分配和GC对象过早优化给我。 JVM在优化这类问题方面做得非常好。
答案 3 :(得分:9)
定义Utility类的最简单方法是作为没有实例的枚举
public enum Utility {;
public static int utilityMethod(int x) { /* ... */ }
}
实用程序类不应该具有任何状态或具有最小状态,因此您不应该担心GC。
您可以将其他有状态类用于特定目的,例如Builder,Factory,您可以根据需要创建对象,并在完成后将其丢弃。
答案 4 :(得分:4)
使用私有构造函数将类设置为非静态是很好的:
答案 5 :(得分:3)
通常,实用程序类包含静态方法而没有属性,这种方法使得在不实例化类的情况下更容易使用它们的方法。希望这会有所帮助。
答案 6 :(得分:2)
如果你能让它们变得静止,那么一定要这样做!
换句话说,如果他们没有状态,他们应该是静态的。
答案 7 :(得分:2)
好吧,如果你没有要存储的状态,那么GC没有任何内容,所以我会选择静态,这样就可以避免任何不必要的堆分配和GC。
答案 8 :(得分:2)
纯实用程序类通常应该是静态的。当你有一个具有明确定义的输入和输出的类,没有副作用和没有状态时,那么根据定义它应该是一个静态类。
一般情况下,在必要之前不要增加复杂性(在这种情况下依赖注入),并且这样做有好处。
答案 9 :(得分:0)
这里没有人提到静态实用程序方法不可扩展。你无法覆盖它们。你不能利用OOP(特别是多态,这是OOP最强大的功能)。这导致代码重复。
P.S。我发现这篇文章非常有帮助。 http://www.yegor256.com/2014/05/05/oop-alternative-to-utility-classes.html