如何在eclipse中提取将字段或常量值转换为参数的方法

时间:2015-10-14 07:43:56

标签: java eclipse refactoring

情况:我正在研究遗留代码并尝试提高可读性。以下示例应该可视化意图:

private static final String CONSTANT_1 = "anyValue";
private static final String CONSTANT_2 = "anyValue";
private static final String CONSTANT_3 = "anyValue";
private static final String CONSTANT_4 = "anyValue";
private static final String CONSTANT_5 = "anyValue";

private final SomeType someField = new SomeType();

private void contentOfSomeMethods(){
    someMethod(someField, CONSTANT_1, true);
    someMethod(someField, CONSTANT_2, true);
    someMethod(someField, CONSTANT_3, true);
    someMethod(someField, CONSTANT_4, false);
    someMethod(someField, CONSTANT_5, false);
}

private void someMethod(SomeType type, String value, boolean someFlag) { }

想象一下,使用大约50个常量大约有50个someMethod调用。我想对该代码执行安全自动重构,以便将contentOfSomeMethods方法更改为

private void contentOfSomeMethods(){
    doItWith(CONSTANT_1);
    doItWith(CONSTANT_2);
    doItWith(CONSTANT_3);
    doItNotWith(CONSTANT_4);
    doItNotWith(CONSTANT_5);
}

生成另外两种方法:

private void doItWith(String value) {
    someMethod(someField, value, true);
}

private void doItNotWith(String value) {
    someMethod(someField, value, false);
}

天真的方法是在局部变量中提取contentOfSomeMethods中的所有常量,然后使用提取方法重构来创建所需的方法。然后内联返回局部变量。但是这个解决方案并没有扩大

另一种方法是使用搜索和替换正则表达式,但这不是一个安全的重构,所以我可以在不注意的情况下破解代码。

你有什么更好的建议吗?你知道Eclipse的一些插件吗?

3 个答案:

答案 0 :(得分:1)

我不知道任何可以直接执行此操作的实用程序。

我认为使用正则表达式是唯一可行的。首先,您需要创建两个目标方法doItWithdoItNotWith。然后,您可以突出显示方法contentOfSomeMethods的内容,点击 Ctrl + F ,并使用以下正则表达式:

  

查找:someMethod\(someField, (\w*), true\);
  替换为:doItWith(\1);

然后

  

查找:someMethod\(someField, (\w*), false\);
  替换为:doItNotWith(\1);

务必检查"正则表达式"和"选择的行"。这是它的照片:

enter image description here

正则表达式将函数调用中使用的常量与(\w*)匹配,然后在替换\1期间使用它。仅在选定的行上使用此正则表达式可以最大限度地减少破坏不相关代码的可能性。

答案 1 :(得分:0)

使用正则表达式并验证

我假设每个someMethod的调用只跨越一行。如果不是这种方法仍然有用但速度较慢。

复制原始文件。

使用ctrl + alt + h显示someMethod的来电者并计算他们的数量。

正则表达式搜索和替换限制在适当的区域:
查找:someMethod(someField,([] * CONSTANT_ [0-9] +)[] *,[] * true [] *)[] *;
替换:doItWith(“$ 1”);
查找:someMethod(someField,([] * CONSTANT_ [0-9] +)[] *,[] * false [] *)[] *;
替换:doItNotWith(“$ 1”);

制作原始文件的差异,新文件仅显示原始文件中已更改的行。

diff --changed-group-format='%<' --unchanged-group-format='' original.java refactored.java | wc

你应该获得与someMethod的调用者相同数量的行。

如果对someMethod的调用是多行的,或者您想要更多验证,只需删除| wc以查看原始文件中修改的行,以确保只修改了正确的行。

答案 2 :(得分:0)

唉,我在Eclipse中一无所知,今天就可以做到这一点。 这是我想在AutoRefactor中实现的一天:https://github.com/JnRouvignac/AutoRefactor/issues/8

然而,到达那里的道路很长。

我今天知道的唯一方法是提取局部变量然后提取方法(如你所建议的)或使用正则表达式(如其他人建议的那样)。