How to refactor constants to enums in Eclipse?

前端 未结 2 1250
时光取名叫无心
时光取名叫无心 2021-01-11 15:33

How do I refactor Java constants to enums with eclipse?

I found no built-in functionality in eclipse: http://help.eclipse.org/juno/index.jsp?topic=%2Forg.eclipse.jdt

相关标签:
2条回答
  • 2021-01-11 16:10

    Here are a set of automated and manual steps to do this refactoring.

    Step 1 Encapsulate field on the constants

    Step 2 (Optional) Rename the constants. Do this if you want to reuse the names.

    Step 3 (Manual) Create the enum using the values of the constants. Give the enum a getValue method that return the constant.

    Step 4 (Manual) Replace the return value in the getters with getValue from the enum.

    Step 5 Inline the getters. Choose "All References", and "Delete method declaration".

    Step 6 Inline the Constants. Choose "All References", and "Delete constant declaration".

    You can stop after 6 if you want, but there is more to be done to use the power of enums.

    Step 7 For each method that uses enum.getValue() as a parameter, replace the constant was passed with the enum.

    Step 7a Change Method Signature to add the Enum as a parameter.

    Step 7b (Manual) Pass the enum instance as the new parameter alongside the getValue call. Make sure you find all the instances, or there will be problems later.

    Step 7c (Manual) In the method, use the new enum parameter instead of the constant. If you missed a call in step 7b your tests will fail here.

    Step 7d Change Method Signature to remove the old Constant.

    Step 8 (Manual) For each use of the enum.getValue() in boolean logic determine if you can use the enum instead.

    Step 9 If the getValue method is no longer used it can be removed.

    Step 9a (Manual) Delete the unused getValue method

    Step 9b (Manual) Delete field and assignment in the constructor.

    Step 9c Change Method Signature to remove the value from the enum constructor.

    Step 9d (Manual) If no other parameters, Remove the the enum constructor.


    For example:

    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);
    }
    
    }
    

    Step 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;
    }
    

    Step 2 Rename Constants

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

    Step 3 Create Enum

        public static enum AnEnum {
        CONSTANT1(_CONSTANT1), CONSTANT2(_CONSTANT2);
    
        private final String value;
    
        AnEnum(String aValue)
        {
            value = aValue;
        }
    
        public String getValue()
        {
            return value;
        }
    }
    

    Step 4 Replace return value in Constant getters

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

    Step 5 Inline the constant getters

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

    Step 6 Inline the Constants

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

    Step 7a Change Method Signiture to add enum as parameter.

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

    Step 7b Pass the enum instance as the new parameter alongside the getValue call

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

    Step 7c Us the new enum parameter instead of the old passed value.

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

    Step 7d Change Method Signature to remove the old Constant

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

    Step 8 For each use of the enum.getValue() in boolean logic determine if you can use the enum instead.

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

    Step 9a delete the unused getValue method Step 9b (Manual) Delete field and assignment in the constructor. Step 9c Change Method Signature to remove the value from the enum constructor. Step 9d (Manual) If no other parameters, Remove the the enum constructor.

        public static enum AnEnum {
        CONSTANT1, CONSTANT2;
    }
    

    So finally the code looks like this:

    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);
    }
    
    }
    
    0 讨论(0)
  • 2021-01-11 16:17

    Refactoring never changes the "external behavior"!

    For example:

    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;
        }
    }
    

    If you refactor _NAME1 to NAME1 (enum) ,the code crashes on instantiation of m. The refactoring would never be successful!

    0 讨论(0)
提交回复
热议问题