几天前,我进行了代码审查,并注意到已经引入了几种static
方法。当我与打开拉动请求的同事交谈时,他告诉我他使副作用免费(not pure)方法static
,因为它有助于处理副作用。他表示,通过这种方式,您可以轻松查看哪些方法会产生副作用,哪些方法不会产生副作用。
我个人非常不同意。尽管有很多static
方法导致副作用(只需查看System
),但static
方法通常(并不总是)会导致问题,例如在测试期间。
然而,static
本身并不坏,我知道每天都是上学日。这是一个我不知道的已知模式吗?制作无副作用的方法有什么好处static
?
答案 0 :(得分:4)
static
方法仅与副作用的关注间接相关。对于私有方法,如果它不解除引用static
,则可以this
。 许多后果之一是这样的方法不会改变对象的状态,这排除了一小类副作用。不要忘记该方法也可以接受参数并改变它们;即使没有它,它总是可以访问和/或改变可通过某些静态变量访问的全局状态。
真正的决策标准是:
this
?this
?如果两个问题的答案都是“否”,那么该方法可以安全地成为static
。
“静态方法为测试带来问题”的抱怨与上述2.相关。在测试中,我们有时必须提供方法的模拟覆盖。在这种情况下,2.的答案是“是”,方法不符合标准。
如果可以,私有方法应该始终是静态的。在瞬间,需要注意static
标记,您将获得以下重要知识:该方法不处理对象的状态,也不调用任何其他实例方法。
如果公共方法满足成为static
的标准,那么它很可能甚至不属于它所在的类,因为它没有与它耦合。在大多数情况下,这种方法是重新定位到静态实用程序类的候选方法。
最后,纯函数的概念(而不仅仅是无副作用)在这里确实很重要:纯函数最不可能需要模拟。它们通常操作简单快捷,只需提供适当的输入即可控制其结果。比较这两种方法:
System.currentTimeMillis()
- 没有副作用,但取决于全局状态,其输出无法控制。通常,它是不可模拟的这一事实意味着测试中的麻烦,因为测试变得不可重复。Character.toUpperCase(char)
- 一个纯函数,执行简单的翻译。你永远不必嘲笑这个。