2016-09-21 29 views
3

前几天我做了代码审查,我注意到已经引入了几个static方法。当我和打开拉请求的同事谈话时,他告诉我他没有副作用(not pure)方法static,因为这样可以帮助处理副作用。他表示,通过这种方式,您可以轻松查看哪些方法会导致副作用,哪些方法不会。使无副作用的方法静态

就我个人而言,我非常不同意这里。尽管有相当多的方法会引起副作用(只需看一下System),但是通常(不总是)会导致问题,例如在测试过程中。

但是,static本身并不坏,我知道每一天的上学日。这是我错过的一种已知模式吗?制造无副作用的方法的优势是什么static

+1

你在说什么样的方法?小型私人助手或公共资料? IDEA甚至有一个检查,告诉你一个私人实例方法应该是静态的,如果它不依赖于'this'。 –

+2

如果一个方法不访问当前实例的状态,并且不是一个接口方法的实现或者一个抽象方法的重载,它应该是静态的,或者不是。静态方法有助于消除代码重复,因为可以在辅助方法中共享通用代码。纯功能(即无副作用的功能)也是优秀的候选人。事实上,没有理由使纯函数成为非静态的。 – dasblinkenlight

+0

术语*纯函数*在这里可能很有用,如果静态函数是纯函数,那么测试就没有问题。 – chrylis

回答

4

static方法只是间接关系到副作用的问题。在私有方法的情况下,如果它不取消引用this,则可以将其制作为static。其中一个许多的后果是,这种方法不会改变对象的状态,从而排除一类狭隘的副作用。不要忘记,该方法也可能接受争论并改变它们;甚至没有它可以通过某个静态变量访问和/或改变可访问的全局状态。

真正的决策标准是这些:

  1. 是否取消引用this的方法?
  2. 该方法是否需要动态调度this的类型?

如果两个问题的答案都是“否”,那么该方法可以安全地变为static

“静态方法产生测试问题”的抱怨与上面的2.有关。在测试中,我们有时必须提供方法的模拟覆盖。在这种情况下,2.的答案是“是”,并且该方法不符合标准。

私有方法应该始终是静态的,如果可以的话。在分秒中注意到static标记,您将获得以下重要知识:该方法不处理对象的状态,也不调用任何其他实例方法。

如果公共方法满足成为static的条件,那么它很可能不属于它所在的类,因为它没有耦合到它。在大多数情况下,这种方法是重新定位到静态工具类的候选者。

最后,函数的概念(而不是无副作用)在这里很重要:纯函数是最不可能需要嘲笑的。它们通常简单且快速执行,只需提供适当的输入即可轻松控制其结果。比较这两种方法:

  • System.currentTimeMillis() —无副作用,而是依赖于全局状态,其输出是无法控制的。通常它不可嘲弄的事实意味着测试中的麻烦,因为测试变得不可重复。
  • Character.toUpperCase(char) —纯功能,执行简单的翻译。你永远不会嘲笑这一个。