如果该类不包含状态,那么使用非静态类是否合理?

时间:2012-08-10 18:47:46

标签: spring oop static

在我的工作场所,似乎目前正在讨论静态课程。我可以理解其中的一部分,他们确实打破了整个单元测试模块化的事情。但是,我看到大量的代码评论要求删除静态类。

一个常见的情况是一个实用程序类,这是一个弹簧注入的一些其他在编译时“已知”的对象。它没有其他成员变量。如果类M正在调用这个静态类,我总是看到建议使这个实用程序类非静态并将其注入到类M中。

这对我没有意义。我没有特别看到它有什么问题,除了它似乎浪费时间并使实用工具类不那么容易使用。据我所知,理由通常是单元测试,但我不喜欢有效代码必须更改以符合测试范例的想法。不可否认,模拟一个简单的静态实用程序类可能会有点过分。

静态类是否适用于此用例,或最好避免使用?

6 个答案:

答案 0 :(得分:2)

我认为这两种方法的差异很小,但只要该类不包含任何状态,使其静态就好一点。我们假设我在A类中有这个代码:

StaticClass.utilMethod()

如果我想在B类中使用此代码,我可以复制和粘贴。就是这样。没有添加成员变量,注入等cmd -c cmd-v。

考虑到您现有的代码使用静态类并修改它将需要工作,它绝对是继续使用静态类的最佳选择。

答案 1 :(得分:1)

我投票支持使用静态类...即一个只有静态方法的类,仅用于实用程序。甚至java也为我们提供了类似java.util.Collectionsjava.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)

自然而然地取决于。

  • 您想如何测试使用静态类的代码?
  • 静态类是否封装了您经常需要进行模拟的行为?
  • 是否有人需要修改这些静态类的行为?

最后:

  • 是否有令人信服的理由注入Spring管理的单例bean?

答案 5 :(得分:1)

  

不可否认,模拟一个简单的静态实用程序类可能会有点过分。

你是对的。静态类只应该用于非常简单的实用程序类,其中没有模拟这样的类的好处。如果您将它们用于任何其他目的,则应重新考虑您的设计。

  

如果该类不包含状态,那么使用非静态类是否合理?

这与国家无关。例如,策略对象通常不包含状态,但它们不是静态的;它们通常实现一个通用接口,需要可互换/可模拟。