如何删除类似基于Java字符串的枚举中的公共代码
我有一个类,其中可能有几个枚举。如何删除类似基于Java字符串的枚举中的公共代码,java,enums,Java,Enums,我有一个类,其中可能有几个枚举。 每个枚举都应该有一个与每个条目关联的字符串值。 为了实现这一点,我添加了一个参数化构造函数,一个支持字符串类的成员,并重写了toString方法 然而,我们可以看到我的两个枚举之间有50%的代码是相同的。它只是支持将字符串映射到枚举值的代码 如何将此代码移动到公共位置并避免代码重复 编辑:当我写America.STATES.NY时,用例是很容易获得“纽约” 以下是我尝试过的, 1) 我尝试使用公共接口,但构造函数不同。 2) 我尝试使用继承,但无法继承枚举 pu
每个枚举都应该有一个与每个条目关联的字符串值。 为了实现这一点,我添加了一个参数化构造函数,一个支持字符串类的成员,并重写了toString方法 然而,我们可以看到我的两个枚举之间有50%的代码是相同的。它只是支持将字符串映射到枚举值的代码 如何将此代码移动到公共位置并避免代码重复 编辑:当我写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;
}
}
}
我喜欢使用的一个典型短语是“数据不是行为的一部分,不属于代码”。明确地说(根据我的经验),采用或转换一个依赖于数据的系统要容易得多,因为它是从某物加载的,而不是用硬编码的值来表示数据
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
或查找名称)时,会更加宽容。如果使用数据库,则可以使代码保持最新,而无需更改项目,只需更改数据库本身。最后,由于所有这些与数据相关的信息都存储在其他地方,因此要处理的代码总量大大减少
您还可以稍后添加一些内容来支持确定给定的行政区域是州还是省或其他什么(我认为枚举非常适合):
使用
EnumMap
可以更好地管理此需求。请检查下面给出的代码:
import java.util.EnumMap;
enum STATES{
NY, CA;
}
enum PROVINCES{
ON, QU;
}
class Main {
public static void main(String[] args) {
EnumMap<STATES, String> statesMap = new EnumMap<STATES, String>(STATES.class);
statesMap.put(STATES.NY , "New York");
statesMap.put(STATES.CA , "California");
System.out.println(statesMap.get(STATES.CA));
EnumMap<PROVINCES, String> provincesMap = new EnumMap<PROVINCES, String>(PROVINCES.class);
provincesMap.put(PROVINCES.ON , "Ontario");
provincesMap.put(PROVINCES.QU , "Qubec");
System.out.println(provincesMap.get(PROVINCES.ON));
}
}
您可以实现EnumUtils类,并将其静态实例添加到每个enum类中。我在这里实现了一个示例:。您可以使用一个接口。我不知道“但是构造器是不同的”应该是什么原因,你能解释一下这个用例吗?基于给定的上下文,我可以推荐使用两个参数创建一个枚举-public enum LocationData(“name”、“type”)。如果需要,可以将类型作为枚举。使用默认方法toString创建接口。在枚举中实现接口,然后可以跳过写入字符串。默认接口方法无法重写对象方法,您需要类似于
asString()
的内容,并在构造字符串时显式调用它。更不用说,您需要一种访问父接口中displayName
的方法,这将需要某种形式的类型检查,或另一种方法,如#getDisplayName
。这两种方法在enum本身的实现中都没有更简洁的方法。我认为最好的方法是不要将此数据存储在枚举中,而是存储其他用于数据的存储类型。除此之外,包含州与省类型的解决方案将缩短写入时间。这似乎只是一个小细节,需要对数据进行重大区分。我不认为您减少了代码,超过了10个州和省,并且您已经超过了行数。一般来说,这会将工作转移到代码中的其他地方,并且无论何时数据发生更改(与boot和bonnet的答案不同),都必须与enum分开维护。
import java.util.EnumMap;
enum STATES{
NY, CA;
}
enum PROVINCES{
ON, QU;
}
class Main {
public static void main(String[] args) {
EnumMap<STATES, String> statesMap = new EnumMap<STATES, String>(STATES.class);
statesMap.put(STATES.NY , "New York");
statesMap.put(STATES.CA , "California");
System.out.println(statesMap.get(STATES.CA));
EnumMap<PROVINCES, String> provincesMap = new EnumMap<PROVINCES, String>(PROVINCES.class);
provincesMap.put(PROVINCES.ON , "Ontario");
provincesMap.put(PROVINCES.QU , "Qubec");
System.out.println(provincesMap.get(PROVINCES.ON));
}
}
California
Ontario