1. 前言
    在漫长的编码生涯中,我们最常见的就是写 if else if 这种东西对于初学者来说确实是很方便,但是维护起来肯定是一堆得麻烦,下面我们来看看怎么使用enum(1),enum+class.forname(2)来解决这个问题,枚举类的使用可以让代码十分的清晰,并且极大程度上可以完成解耦的工作,维护起来也非常简单,

  2. 原代码
    需求: A系统的定义的附件类型和B系统的附件类型 不一致,A需要将附件传给B,但是 B系统的附件类型会一直变化,但是 A系统是面对客户的,不可能每次都因为B增加附件而发布一次,所以需要想个办法解决
    初始版本:

  public String convertImgType(String type) throws RequestException {
        String convert;
        if ("1".equals(type)) {
            convert = "1";// 身份证正
        } else if ("2".equals(type)) {
            convert = "2"; // 身份证反
        } else if ("3".equals(type)) {
            convert = "3";// 本人照片
        }  else {
            convert = "0";
        }
        return convert;
    }

很明显这样写,是十分愚蠢的,怎么改善呢,经过沟通,以后A B 两个系统会进行一致性的附件类型增加,
于是我们考虑就用 enum 来解决之前的愚蠢
首先写一个枚举类:很明显就把这两个type 对应起来就行了

public enum ImageEnum implements IUnexEnum<ImageEnum>{
    TYPE_1("1","1"),
    TYPE_19("19","0"),
    TYPE_20("21","0"),
    ;
    ImageEnum(String code, String desc) {  this.code = code;  this.desc = desc;  }
    private final String code;
    private final String desc;
    @Override
    public String code() {   return code;  }
    @Override
    public String desc() {     return desc;  }
    // 判断code是否相等   @return true-相等, false-不等
    @Override
    public boolean equals(String code) {   return this.code.equals(code);  }
}

抽象的动作 IunexEnum

public interface IUnexEnum<E extends Enum<?>> {
    String code();
    String desc();
    boolean equals(String var1);
}

enum工具类

  public static <E extends Enum<?>> E code2Enum(Class<E> enumClass, String code) {
            if (!IUnexEnum.class.isAssignableFrom(enumClass)) {
                return null;
            } else {
                Enum[] var5;
                int var4 = (var5 = (Enum[])enumClass.getEnumConstants()).length;
                for(int var3 = 0; var3 < var4; ++var3) {
                    IUnexEnum<?> ce = (IUnexEnum)IUnexEnum.class.cast( var5[var3]);
                    if (ce.equals(code)) {
                        return (E)var5[var3];
                    }
                }
                return null;
            }
        }
  1. 初始改造的结果
 public String convertImgType(String type) throws RequestException {
            String convert = "0";
            ImageEnum imageEnum = UnexEnumUtil.code2Enum(ImageEnum.class, type);
            if (imageEnum == null) {
                 convert =type;
            }else{
               convert=imageEnum.desc();
           }
           return convert;
  1. 可能在实践生产中,我们会遇到的还不止 type 转化的问题,还有根据 传入的参数,获取不同的model 所以这里我们也给一个这样的例子 enum+class.forname
    初始版本:一个抽象的 区间类,暂时有四个子类,所以直接用了if else
 public static SectionAb createSections(String sybolend, String sybolStart) {
        boolean endFlag = !Strings.isNullOrEmpty(sybolend)?true:false;
        boolean starFlag = !Strings.isNullOrEmpty(sybolStart)?true:false;
        SectionAb result = null;
        if (endFlag && !starFlag) {
            result = new SectionAbSingleEnd();
        }
        if (endFlag && starFlag) {
            result = new SectionAbBoth();
        }
        if (!endFlag && starFlag) {
            result = new SectionAbSingleStart();
        }
        if (!endFlag && !starFlag) {
            result = new SectionAbNotAll();
        }
        return result;
    }

为了正交性和解耦:其实为了以后不再这里改代码,代码应该就是 不鼓励改动,但是允许扩展
2. 创建 枚举类

public enum SectionTypeEnum implements IUnexEnum<SectionTypeEnum> {
    PROMO_SCOPE("0101", "BOTH"), PROMO_CONDITION("0201", "SINGSTART"),
    PROMO_CONDITION_PARAM("0202", "NOTALL"), PROMO_INCENTIVE("0102", "SINGEND");
    }

包含类路径的枚举类

public enum SectionEnum {

    BOTH("com.xx.install.calc.model.SectionAbBoth"),
    NOTALL("com.xx.install.calc.model.SectionAbNotAll"),
    SINGEND("com.xx.install.calc.model.SectionAbSingleEnd"),
    SINGSTART("com.xx.install.calc.model.SectionAbSingleStart");
    SectionEnum(String className) {
        this.setClassName(className);
    }
    private String className;
    public String getClassName() {
        return className;
    }
    public void setClassName(String className) {
        this.className = className;
    }

}
  1. 改造后
    如果以后还有更改,我们只需要扩展 枚举类和对传入的因子做修改,如果传入的因子会很多种的变化,我们会采用另外一种方法,
  public static SectionAb createSectionByEnum(String sybolend, String sybolStart ) throws Exception{
        String endFlag = !Strings.isNullOrEmpty(sybolend)?"01":"02";
        String starFlag =  !Strings.isNullOrEmpty(sybolStart)?"01":"02";
        String result = UnexEnumUtil.code2Enum(SectionTypeEnum.class , String.valueOf(endFlag+starFlag)).desc();
        String className = SectionEnum.valueOf(result).getClassName();
        SectionAb sectionAb = (SectionAb) Class.forName(className).newInstance();
        return sectionAb;
    }
10-04 11:02