如何在Eclipse中将常量重构为枚举?

时间:2012-11-06 08:30:23

标签: java eclipse refactoring

如何使用eclipse将Java常量重构为枚举?

我发现eclipse中没有内置功能: http://help.eclipse.org/juno/index.jsp?topic=%2Forg.eclipse.jdt.doc.user%2Freference%2Fref-menu-refactor.htm

我找到了一个插件: http://code.google.com/p/constants-to-enum-eclipse-plugin/。我想知道插件是否可行,或者是否有人使用更好的方法。

我总是可以自己创建一个enum类来剪切和粘贴2012年常常繁琐的常量。请不要指向另一个IDE,我太老了也改变了坏习惯; - )

2 个答案:

答案 0 :(得分:3)

以下是一组执行此重构的自动和手动步骤。

步骤1在常量上封装字段

步骤2(可选)重命名常量。如果要重用名称,请执行此操作。

步骤3(手动)使用常量的值创建枚举。为枚举提供一个返回常量的getValue方法。

步骤4(手动)用enum中的getValue替换getter中的返回值。

步骤5内联吸气剂。选择“所有参考”和“删除方法声明”。

步骤6内联常量。选择“所有参考”和“删除常量声明”。

如果你愿意,你可以在6之后停止,但要使用枚举的力量还有很多工作要做。

步骤7对于使用enum.getValue()作为参数的每个方法,替换使用枚举传递的常量。

步骤7a更改方法签名以将Enum添加为参数。

步骤7b(手动)将enum实例作为新参数传递给getValue调用。确保找到所有实例,否则以后会出现问题。

步骤7c(手动)在该方法中,使用新的枚举参数而不是常量。如果你在步骤7b错过了一个电话,你的测试将在这里失败。

步骤7d更改方法签名以删除旧的常量。

步骤8(手动)对于布尔逻辑中enum.getValue()的每次使用,确定是否可以使用枚举。

步骤9如果不再使用getValue方法,则可以将其删除。

步骤9a(手动)删除未使用的getValue方法

步骤9b(手动)删除构造函数中的字段和赋值。

步骤9c更改方法签名以从枚举构造函数中删除值。

步骤9d(手动)如果没有其他参数,请删除枚举构造函数。


例如:

public class Initial {
public static final String CONSTANT1 = "value1";
public static final String CONSTANT2 = "value2";

public void method(String aConstant)
{
    if(aConstant.equals(CONSTANT2))
    {
        //do something
    }
}

public void anotherMethod()
{
    method(CONSTANT1);
}

}

第1步

private static final String CONSTANT1 = "value1";
private static final String CONSTANT2 = "value2";

public void method(String aConstant)
{
    if(aConstant.equals(getConstant2()))
    {
        //do something
    }
}

public void anotherMethod()
{
    method(getConstant1());
}

public static String getConstant1() {
    return CONSTANT1;
}

public static String getConstant2() {
    return CONSTANT2;
}

第2步重命名常量

private static final String _CONSTANT1 = "value1";
private static final String _CONSTANT2 = "value2";
...
public static String getConstant1() {
    return _CONSTANT1;
}

public static String getConstant2() {
    return _CONSTANT2;
}

步骤3创建枚举

    public static enum AnEnum {
    CONSTANT1(_CONSTANT1), CONSTANT2(_CONSTANT2);

    private final String value;

    AnEnum(String aValue)
    {
        value = aValue;
    }

    public String getValue()
    {
        return value;
    }
}

步骤4替换Constant getters中的返回值

    public static String getConstant1() {
    return AnEnum.CONSTANT1.getValue();
}

public static String getConstant2() {
    return AnEnum.CONSTANT2.getValue();
}

步骤5内联常量getter

public void method(String aConstant)
{
    if(aConstant.equals(AnEnum.CONSTANT2.getValue()))
    {
        //do something
    }
}

public void anotherMethod()
{
    method(AnEnum.CONSTANT1.getValue());
}

步骤6内联常量

    public static enum AnEnum {
    CONSTANT1("value1"), CONSTANT2("value2");

步骤7a更改方法签名以将枚举添加为参数。

    public void method(String aConstant, AnEnum theEnum)
    ....
    public void anotherMethod()
{
    method(AnEnum.CONSTANT1.getValue(), null);
}

步骤7b将enum实例作为新参数传递给getValue调用

    public void anotherMethod()
{
    method(AnEnum.CONSTANT1.getValue(), AnEnum.CONSTANT1);
}

步骤7c使用新的枚举参数而不是旧的传递值。

        if(theEnum.getValue().equals(AnEnum.CONSTANT2.getValue()))
    {

步骤7d更改方法签名以删除旧常量

public void method(AnEnum theEnum)
....

public void anotherMethod()
{
    method(AnEnum.CONSTANT1);
}

步骤8对于布尔逻辑中每次使用enum.getValue(),确定是否可以使用枚举。

        if(theEnum.equals(AnEnum.CONSTANT2))
    {
        //do something
    }

步骤9a删除未使用的getValue方法 步骤9b(手动)删除构造函数中的字段和赋值。 步骤9c更改方法签名以从枚举构造函数中删除值。 步骤9d(手动)如果没有其他参数,请删除枚举构造函数。

    public static enum AnEnum {
    CONSTANT1, CONSTANT2;
}

所以最后代码看起来像这样:

public class Step9d {

public static enum AnEnum {
    CONSTANT1, CONSTANT2;
}

public void method(AnEnum theEnum)
{
    if(theEnum.equals(AnEnum.CONSTANT2))
    {
        //do something
    }
}

public void anotherMethod()
{
    method(AnEnum.CONSTANT1);
}

}

答案 1 :(得分:2)

重构永远不会改变“外部行为”!

例如:

public enum Test {
    NAME1("abc");

    Test(String name) {}

    public static final String _NAME1="abc";
    public static void main(String[] args) {
        String k = Test._NAME1;
        String m = Test.NAME1;
    }
}

如果您将_NAME1重构为NAME1(枚举),则代码会在m的实例化时崩溃。重构永远不会成功!