如果我必须设计一个Utility类(例如ByteUtils或StreamUtils或StringUtils),那么对他们来说最佳的设计选择是什么。
- 它们应该是静态类(因为我将没有任何状态可存储)
- 它们应该是非静态类吗(这样,如果不使用对象,它们将被gc'd)
PS:静态类是指具有静态方法的类(而不是内部静态类)
请为此提供设计选择方面的建议?
如果我必须设计一个Utility类(例如ByteUtils或StreamUtils或StringUtils),那么对他们来说最佳的设计选择是什么。
PS:静态类是指具有静态方法的类(而不是内部静态类)
请为此提供设计选择方面的建议?
Answers:
我的实用程序类如下所示:
// 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等),最好使非静态方法使实用程序类可实例化,并使其成为可注入的单例。这样,可以通过模拟实用程序对象来测试使用这些实用程序方法的类。
定义Utility类的最简单方法是作为没有实例的枚举
public enum Utility {;
public static int utilityMethod(int x) { /* ... */ }
}
实用程序类不应具有任何状态或具有最小状态,因此您不必担心GC。
您可以具有用于特定目的的其他状态类,例如Builder,Factory,可以根据需要创建对象,并在完成后将其丢弃。
final默认情况下,枚举是。
enum可以具有可变字段,实现接口和抽象方法,因此它们不仅仅是常量。;)
enum混进去然而改变在凌晨3点累工程师如何跳上咖啡因会读的东西,让他纳闷了一下是怎么回事什么。这不是一个常见的成语。使用class并开心。
enum,您是在向读者说明,在其设计中隐藏了枚举的原因。没有。您只想使其比放入final和私有构造函数容易,这都不是IMO的问题。那是不寻常的成语。您看到有人试图实例化实用程序的静态方法类吗?这有关系吗?如果有人认为该类提供了所需的方法,他们就会知道它们是什么-为什么要实例化它?如果他们这样做会怎样?不多。
如果您可以将它们设为静态,那么一定要这样做!
换句话说,如果它们没有状态,则它们应该是静态的。
这里没有人提到静态实用程序方法是不可扩展的。您无法覆盖它们。您无法利用OOP(尤其是多态性,这是OOP的最强大功能)。这导致代码重复。
PS我发现这篇文章非常有帮助。http://www.yegor256.com/2014/05/05/oop-alternative-to-utility-classes.html