If I have to design a Utility class( such as ByteUtils or StreamUtils or StringUtils), what is the best design choice for them.
如果我必须设计一个实用程序类(例如ByteUtils或StreamUtils或StringUtils),那么它们的最佳设计选择是什么。
- Should they be static classes (as I won't have any states to store)
- 它们应该是静态类(因为我没有任何状态可以存储)
- Should they be non-static classes ( so that if the objects are not used, they will be gc'd)
- 它们是否是非静态类(以便如果不使用对象,它们将是gc d)
PS: By static class, I meant a class with static methods(and not the inner static class)
PS:所谓的静态类,我指的是带有静态方法的类(而不是内部静态类)
Please give advice on design choices for this ?
请给出关于设计选择的建议。
10 个解决方案
#1
37
If it is a general purpose utility, static is IMO better. You stated that you will not have any states to store, so I don't see why should you make it non-static. Declaring it to be static will save memory too.
如果是一种通用实用工具,静态在我看来更好。你说你没有任何状态可以存储,所以我不明白你为什么要让它是非静态的。声明它为静态也将保存内存。
#2
54
My utility classes look like this:
我的实用程序类如下:
// 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() {
}
// ...
}
Note that, although this makes the utility methods easily testable, and easily accessible from the outside, it also makes the classes using them hard to unit-test, because it's not easy to mock these utility methods. Having too many of such utility classes can be a sign of a lack of OO design (procedural programming), and can really make the code hard to test.
请注意,尽管这使实用程序方法易于测试,并且很容易从外部访问,但也使使用它们的类难于进行单元测试,因为模仿这些实用程序方法并不容易。拥有太多这样的实用程序类可能是缺乏面向对象设计(过程性编程)的一个标志,并且会使代码很难测试。
If you're using a dependency injection framework (Spring, Guice, whatever), it might be a good idea to just make the utility class instantiatable, with non-static methods, and make it an injectable singleton. This way, classes using these utility methods can be tested by mocking the utility object.
如果您正在使用依赖注入框架(Spring、Guice等),那么最好使用非静态方法实例化实用程序类,并使其成为可注入的单例对象。这样,使用这些实用程序方法的类可以通过mock实用程序对象进行测试。
#3
20
Just because something can be static, doesn't mean it should be static.
仅仅因为某些东西可以是静态的,并不意味着它应该是静态的。
There is another consideration to all this: mocking. It's harder to mock static methods in your tests than it is to mock the behaviour of an instance of a class.
这一切还有另外一个考虑:嘲笑。在测试中模拟静态方法比模拟类实例的行为要困难得多。
Talk of unnecessary heap allocations and GCing of objects smacks of premature optimisation to me. The JVM will do a pretty good job at optimising away this sort of issue.
在我看来,谈论不必要的堆分配和对象的GCing有点过早的优化。JVM在优化这类问题方面做得很好。
#4
10
The simplest way to define a Utility class is as an enum with no instances
定义实用程序类的最简单的方法是作为一个没有实例的枚举
public enum Utility {;
public static int utilityMethod(int x) { /* ... */ }
}
A utility class shouldn't have any state or have minimal state so you shouldn't worrying about GCs.
一个实用程序类不应该有任何状态或最小状态,所以您不应该担心GCs。
You can have other stateful classes for specific purposes like Builder, Factory, you can create the object as desired and discard it when you have finished.
您可以有其他有状态类用于特定目的,比如Builder、Factory,您可以根据需要创建对象,并在完成后丢弃它。
#5
3
Its good to make the class as non-static with a private constructor:
使用私有构造函数使类成为非静态类是有好处的:
- if we make the class static then class will be loaded when the application is deployed, if it is non-static then the class will be loaded when there is a call to one of its static methods
- 如果我们使类静态,那么当应用程序被部署时,类将被加载,如果它是非静态的,那么当调用它的静态方法时,类将被加载。
- creating a private constructor will avoid instantiating the class
- 创建私有构造函数将避免实例化类
#6
2
Usually utility classes contain static methods and no attributes, this approach makes it easier to use their methods without instantiating the class. Hope this helps.
通常,实用程序类包含静态方法而不包含属性,这种方法使得在不实例化类的情况下更容易使用它们的方法。希望这个有帮助。
#7
2
Pure utility classes should usually be static. When you have a class with well-defined input and output, no side effects and no state, then by definition it should be a static class.
纯实用程序类通常应该是静态的。当您有一个具有定义良好的输入和输出、没有副作用和状态的类时,那么根据定义,它应该是一个静态类。
In general, don't add complexity (dependency injection in this case) before it's necessary and there's a benefit in doing it.
通常,在必要之前不要增加复杂性(在本例中是依赖注入),这样做有好处。
#8
1
If you can make them static, then definitely do so!
如果你可以让它们保持静态,那么一定要这样做!
In other words, if they don't have state, they should be static.
换句话说,如果它们没有状态,它们应该是静态的。
#9
1
Well, if you have no state to store then there is nothing to GC, so I would go with static, that way you avoid any unnecessary heap allocations and GC.
如果您没有状态存储,那么就没有GC的内容,所以我将使用静态方法,这样您就可以避免不必要的堆分配和GC。
#10
0
Nobody here mention that static utility methods are not extensible. You cannot override them. You cannot take advantage of OOP (particularly polymorphysm, which is most powerful feature of OOP). That leads to code duplication.
这里没有人提到静态实用程序方法是不可扩展的。你不能覆盖它们。您不能利用OOP(特别是多态性,这是OOP最强大的特性)。这会导致代码重复。
P.S. I found this article very helpful. http://www.yegor256.com/2014/05/05/oop-alternative-to-utility-classes.html
附注:我发现这篇文章很有帮助。http://www.yegor256.com/2014/05/05/oop-alternative-to-utility-classes.html
#1
37
If it is a general purpose utility, static is IMO better. You stated that you will not have any states to store, so I don't see why should you make it non-static. Declaring it to be static will save memory too.
如果是一种通用实用工具,静态在我看来更好。你说你没有任何状态可以存储,所以我不明白你为什么要让它是非静态的。声明它为静态也将保存内存。
#2
54
My utility classes look like this:
我的实用程序类如下:
// 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() {
}
// ...
}
Note that, although this makes the utility methods easily testable, and easily accessible from the outside, it also makes the classes using them hard to unit-test, because it's not easy to mock these utility methods. Having too many of such utility classes can be a sign of a lack of OO design (procedural programming), and can really make the code hard to test.
请注意,尽管这使实用程序方法易于测试,并且很容易从外部访问,但也使使用它们的类难于进行单元测试,因为模仿这些实用程序方法并不容易。拥有太多这样的实用程序类可能是缺乏面向对象设计(过程性编程)的一个标志,并且会使代码很难测试。
If you're using a dependency injection framework (Spring, Guice, whatever), it might be a good idea to just make the utility class instantiatable, with non-static methods, and make it an injectable singleton. This way, classes using these utility methods can be tested by mocking the utility object.
如果您正在使用依赖注入框架(Spring、Guice等),那么最好使用非静态方法实例化实用程序类,并使其成为可注入的单例对象。这样,使用这些实用程序方法的类可以通过mock实用程序对象进行测试。
#3
20
Just because something can be static, doesn't mean it should be static.
仅仅因为某些东西可以是静态的,并不意味着它应该是静态的。
There is another consideration to all this: mocking. It's harder to mock static methods in your tests than it is to mock the behaviour of an instance of a class.
这一切还有另外一个考虑:嘲笑。在测试中模拟静态方法比模拟类实例的行为要困难得多。
Talk of unnecessary heap allocations and GCing of objects smacks of premature optimisation to me. The JVM will do a pretty good job at optimising away this sort of issue.
在我看来,谈论不必要的堆分配和对象的GCing有点过早的优化。JVM在优化这类问题方面做得很好。
#4
10
The simplest way to define a Utility class is as an enum with no instances
定义实用程序类的最简单的方法是作为一个没有实例的枚举
public enum Utility {;
public static int utilityMethod(int x) { /* ... */ }
}
A utility class shouldn't have any state or have minimal state so you shouldn't worrying about GCs.
一个实用程序类不应该有任何状态或最小状态,所以您不应该担心GCs。
You can have other stateful classes for specific purposes like Builder, Factory, you can create the object as desired and discard it when you have finished.
您可以有其他有状态类用于特定目的,比如Builder、Factory,您可以根据需要创建对象,并在完成后丢弃它。
#5
3
Its good to make the class as non-static with a private constructor:
使用私有构造函数使类成为非静态类是有好处的:
- if we make the class static then class will be loaded when the application is deployed, if it is non-static then the class will be loaded when there is a call to one of its static methods
- 如果我们使类静态,那么当应用程序被部署时,类将被加载,如果它是非静态的,那么当调用它的静态方法时,类将被加载。
- creating a private constructor will avoid instantiating the class
- 创建私有构造函数将避免实例化类
#6
2
Usually utility classes contain static methods and no attributes, this approach makes it easier to use their methods without instantiating the class. Hope this helps.
通常,实用程序类包含静态方法而不包含属性,这种方法使得在不实例化类的情况下更容易使用它们的方法。希望这个有帮助。
#7
2
Pure utility classes should usually be static. When you have a class with well-defined input and output, no side effects and no state, then by definition it should be a static class.
纯实用程序类通常应该是静态的。当您有一个具有定义良好的输入和输出、没有副作用和状态的类时,那么根据定义,它应该是一个静态类。
In general, don't add complexity (dependency injection in this case) before it's necessary and there's a benefit in doing it.
通常,在必要之前不要增加复杂性(在本例中是依赖注入),这样做有好处。
#8
1
If you can make them static, then definitely do so!
如果你可以让它们保持静态,那么一定要这样做!
In other words, if they don't have state, they should be static.
换句话说,如果它们没有状态,它们应该是静态的。
#9
1
Well, if you have no state to store then there is nothing to GC, so I would go with static, that way you avoid any unnecessary heap allocations and GC.
如果您没有状态存储,那么就没有GC的内容,所以我将使用静态方法,这样您就可以避免不必要的堆分配和GC。
#10
0
Nobody here mention that static utility methods are not extensible. You cannot override them. You cannot take advantage of OOP (particularly polymorphysm, which is most powerful feature of OOP). That leads to code duplication.
这里没有人提到静态实用程序方法是不可扩展的。你不能覆盖它们。您不能利用OOP(特别是多态性,这是OOP最强大的特性)。这会导致代码重复。
P.S. I found this article very helpful. http://www.yegor256.com/2014/05/05/oop-alternative-to-utility-classes.html
附注:我发现这篇文章很有帮助。http://www.yegor256.com/2014/05/05/oop-alternative-to-utility-classes.html