How can I eliminate duplicated Enum code?

后端 未结 15 827
眼角桃花
眼角桃花 2020-12-24 13:40

I have a large number of Enums that implement this interface:

/**
 * Interface for an enumeration, each element of which can be uniquely identified by its co         


        
相关标签:
15条回答
  • 2020-12-24 13:50

    I had a similar issue with a localization component that I wrote. My component is designed to access localized messages with enum constants that index into a resource bundle, not a hard problem.

    I found that I was copying and pasting the same "template" enum code all over the place. My solution to avoid the duplication is a code generator that accepts an XML configuration file with the enum constant names and constructor args. The output is the Java source code with the "duplicated" behaviors.

    Now, I maintain the configuration files and the generator, not all of the duplicated code. Everywhere I would have had enum source code, there is now an XML config file. My build scripts detect out-of-date generated files and invoke the code generator to create the enum code.

    You can see this component here. The template that I was copying and pasting is factored out into an XSLT stylesheet. The code generator runs the stylesheet transformation. An input file is quite concise compared to the generated enum source code.

    HTH,
    Greg

    0 讨论(0)
  • 2020-12-24 13:54

    If you really want inheritance, don't forget that you can implement the enum pattern yourself, like in the bad old Java 1.4 days.

    0 讨论(0)
  • 2020-12-24 13:55

    You could factor the duplicated code into a CodeableEnumHelper class:

    public class CodeableEnumHelper {
        public static CodeableEnum getByCode(String code, CodeableEnum[] values) {
            for (CodeableEnum e : values) {
                if (e.getCode().equalsIgnoreCase(code)) {
                    return e;
                }
            }
            return null;
        }
    }
    

    Each CodeableEnum class would still have to implement a getByCode method, but the actual implementation of the method has at least been centralized to a single place.

    public enum IMType implements CodeableEnum {
        ...
        public IMType getByCode(String code) {
            return (IMType)CodeableEnumHelper.getByCode(code, this.values());
        } 
    }
    
    0 讨论(0)
  • 2020-12-24 13:55

    Here I have another solution:

    interface EnumTypeIF {
    String getValue();
    
    EnumTypeIF fromValue(final String theValue);
    
    EnumTypeIF[] getValues();
    
    class FromValue {
      private FromValue() {
      }
    
      public static EnumTypeIF valueOf(final String theValue, EnumTypeIF theEnumClass) {
    
        for (EnumTypeIF c : theEnumClass.getValues()) {
          if (c.getValue().equals(theValue)) {
            return c;
          }
        }
        throw new IllegalArgumentException(theValue);
      }
    }
    

    The trick is that the inner class can be used to hold "global methods".

    Worked pretty fine for me. OK, you have to implement 3 Methods, but those methods, are just delegators.

    0 讨论(0)
  • 2020-12-24 13:56

    About as close as I got to what you want was to create a template in IntelliJ that would 'implement' the generic code (using enum's valueOf(String name)). Not perfect but works quite well.

    0 讨论(0)
  • 2020-12-24 13:59

    I don't think this is possible. However, you could use the enum's valueOf(String name) method if you were going to use the enum value's name as your code.

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