在我的工作场所,似乎目前正在讨论静态课程。我可以理解其中的一部分,他们确实打破了整个单元测试模块化的事情。但是,我看到大量的代码评论要求删除静态类。
一个常见的情况是一个实用程序类,这是一个弹簧注入的一些其他在编译时“已知”的对象。它没有其他成员变量。如果类M正在调用这个静态类,我总是看到建议使这个实用程序类非静态并将其注入到类M中。
这对我没有意义。我没有特别看到它有什么问题,除了它似乎浪费时间并使实用工具类不那么容易使用。据我所知,理由通常是单元测试,但我不喜欢有效代码必须更改以符合测试范例的想法。不可否认,模拟一个简单的静态实用程序类可能会有点过分。
静态类是否适用于此用例,或最好避免使用?
答案 0 :(得分:2)
我认为这两种方法的差异很小,但只要该类不包含任何状态,使其静态就好一点。我们假设我在A类中有这个代码:
StaticClass.utilMethod()
如果我想在B类中使用此代码,我可以复制和粘贴。就是这样。没有添加成员变量,注入等cmd -c cmd-v。
考虑到您现有的代码使用静态类并修改它将需要工作,它绝对是继续使用静态类的最佳选择。
答案 1 :(得分:1)
我投票支持使用静态类...即一个只有静态方法的类,仅用于实用程序。甚至java也为我们提供了类似java.util.Collections
和java.util.Arrays
答案 2 :(得分:1)
如果您假装您的静态类不属于您,那么它就是.NET框架的一部分,您的团队将如何处理它?他们的回答是我的回答。换句话说,如果他们对这个问题的回答与他们要求你做的事情不一致,那么他们可能要么改变他们使用.NET静态类的方式,要么改变他们如何使用你的静态类。
答案 3 :(得分:1)
我避免使用静态类(假设我们实际上是在讨论包含静态方法的类),并且为了可测试性而这样做。
如果您使用静态方法,那么您将很难模拟/存储使用所述静态进行单元测试的代码部分。
考虑一下:
public String myMethod() {
String complicatedStringOutput = MyUtility.createComplicatedStringOutput();
//do some more complicated work on this String
}
要为此方法编写单元测试,如何在不需要测试complicatedStringOutput
的创建的情况下将其作为“真正的单元测试”?在我的单元测试中,我更喜欢只测试单元测试的焦点方法。
将其更改为:
public String myMethod(MyNonStaticUtility util) {
String complicatedStringOutput = util.createComplicatedStringOutput();
//do some more complicated work on this String
}
突然之间,这门课更容易为'真正的单元测试'编写。您可以使用存根或模拟来控制MyNonStaticUtility
的行为。
所有这一切,都取决于您(或您的业务部门)。如果您重视单元测试并认为对复杂代码进行良好的测试覆盖很重要,那么这是首选方法。如果你没有时间/金钱来投资“修复”你的代码,那么它就不会发生。
答案 4 :(得分:1)
自然而然地取决于。
最后:
答案 5 :(得分:1)
不可否认,模拟一个简单的静态实用程序类可能会有点过分。
你是对的。静态类只应该用于非常简单的实用程序类,其中没有模拟这样的类的好处。如果您将它们用于任何其他目的,则应重新考虑您的设计。
如果该类不包含状态,那么使用非静态类是否合理?
这与国家无关。例如,策略对象通常不包含状态,但它们不是静态的;它们通常实现一个通用接口,需要可互换/可模拟。