Java 使无副作用的方法静态化

Java 使无副作用的方法静态化,java,static,Java,Static,几天前,我做了一次代码回顾,我注意到已经引入了几种静态方法。当我与打开pull请求的同事交谈时,他告诉我他创建了无副作用()方法static,因为这有助于处理副作用。他说,通过这种方式,你很容易看到哪些方法会导致副作用,哪些不会 就我个人而言,我强烈反对这一点。尽管有相当多的静态方法会导致副作用(请看一看),静态方法通常(并非总是)会导致问题,例如在测试期间 然而,static本身并不坏,我知道每天都是上学的日子。这是我丢失的已知模式吗?无副作用的静态方法有什么好处?静态方法只间接与副作用有关。

几天前,我做了一次代码回顾,我注意到已经引入了几种
静态
方法。当我与打开pull请求的同事交谈时,他告诉我他创建了无副作用()方法
static
,因为这有助于处理副作用。他说,通过这种方式,你很容易看到哪些方法会导致副作用,哪些不会

就我个人而言,我强烈反对这一点。尽管有相当多的
静态
方法会导致副作用(请看一看),
静态
方法通常(并非总是)会导致问题,例如在测试期间


然而,
static
本身并不坏,我知道每天都是上学的日子。这是我丢失的已知模式吗?无副作用的静态方法有什么好处?

静态方法只间接与副作用有关。在私有方法的情况下,如果它不取消对该
的引用,则可以将其设置为
静态
。许多后果之一是,这种方法不会改变对象的状态,从而排除了一类狭隘的副作用。不要忘记该方法也可以接受参数并对其进行变异;即使没有它,它也可以通过一些静态变量访问和/或改变全局状态

真正的决策标准如下:

  • 该方法是否取消引用此
  • 该方法是否受
    类型的动态调度约束
  • 如果这两个问题的答案都是“否”,则该方法可以安全地变为
    静态

    关于“静态方法造成测试问题”的投诉与2有关。在上面在测试中,我们有时必须提供方法的模拟重写。在这种情况下,答案是2。为“是”,且该方法不符合标准

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

    如果一个公共方法满足成为
    静态的标准,那么它很可能甚至不属于它所在的类,因为它与它没有耦合。在大多数情况下,这种方法是重新定位到静态实用程序类的候选方法

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

    • System.currentTimeMillis()
      -无副作用,但取决于全局状态,其输出无法控制。当测试变得不可重复时,它不可模仿的事实通常意味着测试中的麻烦
    • Character.toUpperCase(char)
      -一个纯函数,执行简单的翻译。你永远不必嘲笑这个

    你在说什么样的方法?私人小帮手还是公共物品?IDEA甚至有一个检查告诉您,如果私有实例方法不依赖于
    ,那么它应该是静态的。如果方法不访问当前实例的状态,并且不是接口方法的实现或抽象方法的重写,那么它应该是静态的,不管是否有副作用。静态方法有助于消除代码重复,因为公共代码可以在助手方法中共享。纯函数(即无副作用的函数)也是很好的候选函数。事实上,没有理由让纯函数成为非静态函数。我在这里看不到纯函数和非纯函数之间的区别。这是关于需要取消引用此
    并接受动态调度的问题。@beatngu13您的问题也太宽泛了,因为大多数“利弊”问题都太宽泛了。
    public
    private
    具有非常不同的性质,甚至是两个独立的问题。创建
    私有
    方法
    静态
    是一件轻而易举的事,但公共方法通常需要动态调度。如果它们不是(
    final
    方法)并且不访问
    this
    ,则它们不属于该类,应该移动到静态实用程序类。