随着时间的推移......在java项目中引入了许多实用方法来完成更复杂和简单的任务。
当使用静态方法时,我们在代码中引入了紧密耦合,这使我们的代码更难测试,尤其是在实用程序方法非常复杂的情况下。
我只是认为现在很难管理和测试这些实用程序。请指导我避免使用这些实用程序方法以及如何组织现有项目以删除所有 STATIC 实用程序。
你能帮我避免使用静态方法吗?
There is nothing wrong with having lots of static methods.
Static methods are (or should be, read on) stateless, which makes them the easiest methods to test - there's no setup, just call them.
You don't need mocking, because there is no state to deal with.
Regarding being stateless, technically static methods can be stateful if they use static variables to store state. If this is the case, from a good-design perspective they should be converted to instance methods using instance variables to store state, employing the singleton pattern if required.
与当前可用的其他答案相矛盾:静态方法很糟糕!
它们确实引入了强耦合。是的,有些情况是可以接受的。是的,您可以通过使内部使用的策略可交换来为静态方法内部创建接缝。但根据经验,静态仍然很糟糕。
要回答这个问题,如何摆脱静态方法。很简单:把它们放在一个合适的对象上。所有的静电都消失了。我们改进了代码吗?还不算多。如果我们更换
callToStaticMethod()
和
new X().callToNoLongerStaticMethod()
我们用构造函数调用替换了静态调用,构造函数调用本质上只是另一个静态方法。但是现在你X
的只是另一个依赖,所以你可以注入它:
class A{
private final X x;
A(X aX){
x = aX;
}
}
注意:不需要为此使用 Spring 或任何其他框架。如果您觉得它提供了一个使用默认实现的构造函数。如果您是纯粹主义者,请为 X 引入一个接口。
A
不依赖于实现的测试X
变得微不足道且显而易见。X
以任何方式替换都是一样的。
Static utility methods are not so bad. You can hide a package-private strategy behind the static call. This can be easily tested (and replaced) given that the test case belongs to the same package. Moreover, it makes the code very readable. Of course, the clients of the static utility method can still only use one implementation in their tests. So here is some inflexibility.
Bohemian is right when talking about state. If your static utilities have state you are doing something wrong.
About your question: If you want to avoid static methods you can use the spring framework and define different implementations of utilities that you use and test in different contexts. In this case, however, access to these objects is not so convenient as you must first obtain a reference to the context that knows your utility object.
一组属于一个类的静态实用程序方法没有错。参见例如java.util.Collections
。如果该类中对 a 进行操作的每个方法List
都将在List
接口本身中指定,则它们必须由所有子类实现。只要它们可以通过公共List
方法实现,就没有问题。
当然,一旦你开始向接口添加方法(或者在类的情况下,公开方法)只是为了能够将功能放入静态方法而不是类本身,那么你就走错了路。