当前位置:  开发笔记 > 编程语言 > 正文

消除重复的枚举代码

如何解决《消除重复的枚举代码》经验,为你挑选了3个好方法。

我有大量实现此接口的枚举:

/**
 * Interface for an enumeration, each element of which can be uniquely identified by it's code
 */
public interface CodableEnum {

    /**
     * Get the element with a particular code
     * @param code
     * @return
     */
    public CodableEnum getByCode(String code);

    /**
     * Get the code that identifies an element of the enum
     * @return
     */
    public String getCode();
}

一个典型的例子是:

public enum IMType implements CodableEnum {

    MSN_MESSENGER("msn_messenger"),
    GOOGLE_TALK("google_talk"),
    SKYPE("skype"),
    YAHOO_MESSENGER("yahoo_messenger");

    private final String code;

    IMType (String code) {
        this.code = code;
    }

    public String getCode() {
        return code;
    }   

    public IMType getByCode(String code) {
        for (IMType e : IMType.values()) {
            if (e.getCode().equalsIgnoreCase(code)) {
                return e;
            }
        }
    }
}

可以想象,这些方法在CodableEnum的所有实现中几乎完全相同.我想消除这种重复,但坦率地说不知道如何.我尝试使用如下的类:

public abstract class DefaultCodableEnum implements CodableEnum {

    private final String code;

    DefaultCodableEnum(String code) {
        this.code = code;
    }

    public String getCode() {
        return this.code;
    }   

    public abstract CodableEnum getByCode(String code);  
}

但事实证明这是无用的,因为:

    枚举不能扩展类

    枚举元素(SKYPE,GOOGLE_TALK等)不能扩展类

    我无法提供getByCode()的默认实现,因为DefaultCodableEnum本身不是Enum.我尝试更改DefaultCodableEnum以扩展java.lang.Enum,但似乎不允许这样做.

任何不依赖反思的建议?谢谢,唐



1> 小智..:

您可以将重复的代码分解为一个CodeableEnumHelper类:

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

每个CodeableEnum类仍然必须实现一个getByCode方法,但该方法的实际实现至少已集中到一个地方.

public enum IMType implements CodeableEnum {
    ...
    public IMType getByCode(String code) {
        return (IMType)CodeableEnumHelper.getByCode(code, this.values());
    } 
}



2> Alex Miller..:

抽象枚举可能非常有用(目前不允许).但是,如果您想在Sun中为某个人添加游戏来添加它,则存在一个提案和原型:

http://freddy33.blogspot.com/2007/11/abstract-enum-ricky-carlson-way.html

Sun RFE:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6570766



3> Tom Hawtin -..:

整理戴夫的代码:

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

public enum IMType implements CodableEnum {
    ...
    public IMType getByCode(String code) {
        return CodeableEnumHelper.getByCode(code, values());
    } 
}

或者更有效率:

public class CodeableEnumHelper {
    public static  Map mapByCode(
        E[] values
    ) {
        Map map = new HashMap();
        for (E e : values) {
            map.put(e.getCode().toLowerCase(Locale.ROOT), value) {
        }
        return map;
    }
}

public enum IMType implements CodableEnum {
    ...
    private static final Map byCode =
        CodeableEnumHelper.mapByCode(values());
    public IMType getByCode(String code) {
        return byCode.get(code.toLowerCase(Locale.ROOT));
    } 
}

推荐阅读
云聪京初瑞子_617
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有