如何确定Java函数的副作用?

如何确定Java函数的副作用?,java,eclipse,Java,Eclipse,我正在处理一个对象,特别是它的一个函数,它看起来像这样: public class Dog { private ArrayList<Paw> paws; private double age; private Tongue tongue; public Dog(ArrayList<Paw> paws, double age, Tongue tongue) { this.paws = paws; this.a

我正在处理一个对象,特别是它的一个函数,它看起来像这样:

public class Dog {
    private ArrayList<Paw> paws;
    private double age;
    private Tongue tongue;

    public Dog(ArrayList<Paw> paws, double age, Tongue tongue) {
        this.paws = paws;
        this.age = age;
        this.tongue = tongue;
    }

    public void bark() {
        // ... about 100 lines of side effects operating
        // on the object's global members ...
    }
}
公共级狗{
私人ArrayList爪子;
私人双倍年龄;
私语;
公犬(ArrayList爪,双倍年龄,舌头){
this.paws=爪;
这个。年龄=年龄;
这个。舌头=舌头;
}
公共空间{
//…大约有100行副作用正在运行
//在对象的全局成员上。。。
}
}
我真的想修复这些副作用,并将对象重构成只做一件事的函数

Eclipse中是否有一个自动过程来标记可能的副作用


如果没有,是否有一个手动算法我可以遵循,这样我就不会在兔子洞里迷路?

我会创建一个单元测试来测试你的旧
类,包括所有的“副作用”(不太清楚你在这里的意思)

假设您的单元测试通过了,那么您可以开始重构(使用Eclipse,选择适当的行并使用右键单击,重构,提取方法可能是您的朋友),并继续使用您的单元测试来检查重构是否破坏了任何东西

编辑:


要了解您的
Paw
tangle
类的属性还有哪些变化,您可以在
bark()
使用的任何属性上设置修改观察点(即,在属性上设置断点,右键单击断点,断点属性,取消勾选“访问”),然后,当您在调试器中运行应用程序时,每次属性发生任何更改时,调试器都会停止。

我不知道有什么自动过程

至于手动算法,如果您将所有类字段设置为final,则大多数地方都会出现错误,这是由于
bark()
的副作用。(另一种方法是重命名它们,但也会标记从它们读取的内容),这样您就可以很容易地找到副作用。慢慢地重构成更小的函数,直到
bark()
没有错误

ArrayList的爪子不会被
final
技巧所覆盖,因为您仍然可以
add()、remove()
等。因此,这可能是一个需要重新命名的名称

Eclipse中是否有一个自动过程来标记可能的方面 影响

不,没有

如果没有,是否有一个手动算法我可以遵循,这样我就不会迷路 在兔子洞里


您可以从注释(
ctrl+/
)对象的所有全局成员开始。所以在你的函数中,你会有红色下划线的单词,你必须用参数传递或局部变量来修复它们。后来取消了成员的注释。在Eclipse中,您还可以使用快捷方式
Ctrl+Shift+M
进行方法提取。对于refector,还有一个非常有用的快捷方式
Ctrl+Shift+R
用于更改变量名。

我指的是任何改变传递到方法中的对象数据的东西。这个答案并不真正有效,因为它回避了这个问题。如果我的问题是,“我如何重构这个方法?”那么一个循环的答案是,“对方法进行单元测试,然后重构它。”我很欣赏提取方法和单元测试建议——但我相信你比我领先了一步。这非常有用——我将尝试它(和其他方法)。如果在一点时间内没有更好的答案,我会接受这个访问建议。谢谢+1单元测试和重构应该经常(如果不是总是)走在一起。我几乎否决了这一点。如果一个方法有100行代码产生大量副作用,那么创建单元测试几乎是不可能的。听起来OP不知道代码应该做什么,这就是为什么他要重构来理解它。OP重构成“只做一件事的函数”后,他/她就可以编写单元测试了。@user949300您这样批评他们beny23答案的第一部分是正确的。不过,第二部分(编辑)是有用的建议。最后一个技巧很有用,谢谢。不幸的是,它在某些情况下在方法中不起作用,因为该方法将数据从全局复制到局部变量(或者该方法调用全局变量上的另一个方法)。注释很有用,谢谢。我将从这开始。