首页 > 解决方案 > 如何在类似的基于 Java 字符串的枚举中删除通用代码

问题描述

我有一个类,其中可能有几个枚举。
每个枚举都应该有一个与每个条目关联的字符串值。为了实现这一点,我添加了一个参数化构造函数、一个支持字符串类成员并覆盖了 toString 方法。

但是可以看到我的两个枚举之间的代码有 50% 是相同的。它只是支持将字符串映射到 Enum 值的代码。

如何将此代码移动到公共位置并避免代码重复

编辑:用例是在我编写 America.STATES.NY 时轻松获得“纽约”。

这是我尝试过的,
1)我尝试使用通用接口,但构造函数不同。
2)我尝试使用继承,但枚举不能被继承

public class America {
    public enum STATES {
        NY("New York"), CA("California");
        String displayName;

        STATES(String displayName) {
            this.displayName = displayName;
        }

        @Override
        public String toString() {
            return this.displayName;
        }
    }

    public enum PROVINCES {
        ON("Ontario"), QU("Qubec");

        String displayName;

        PROVINCES(String displayName) {
            this.displayName = displayName;
        }

        @Override
        public String toString() {
            return this.displayName;
        }

    }
}

标签: javaenums

解决方案


我喜欢使用的一个典型短语是“数据不是行为的一部分,也不属于代码”。需要明确的是(根据我的经验),采用或翻译一个依赖于从某些东西加载的数据的系统比用硬编码值表示数据要容易得多。

public class Region {
    private final String name;
    public Region(String name) { this.name = name; }
    public String getDisplayName() { return this.name; }
    public String toString() { return getDisplayName(); }
}

public class Country {
    //keeps a map/list of "regions", whether states or provinces or some other type
    public Region getRegion(Object key); //lookup a region based on some key, I'll use strings here
}

Country america = /* a country supplied from somewhere */;
String name = america.getRegion("NY").getDisplayName(); //"New York"

这种类型的方法虽然对于代码中的硬编码引用(getRegion("NY")Region姓名)。如果您使用数据库,您可以使您的代码保持最新,而无需更改项目,只需更改数据库本身。最后,由于所有这些与数据相关的信息都存储在其他地方,因此要处理的代码总量大大减少。

您还可以稍后添加一些内容来支持确定给定的行政区域是州还是省或其他东西(我认为枚举非常适合):

public enum RegionType {
    STATE, PROVINCE, ADMIN_REGION, OTHER,
    ;
}

推荐阅读