我有几个符合常见界面的枚举:
interface TableColumns { String getColumnName(); int getColumnIndex(); ColumnType getColumnType(); boolean isEditable(); int getColumnWidth(); }
典型的实现是:
enum PointsTableColumns implements TrendTableColumns { POINTS_COLUMN("points_column",false,ColumnType.TEXT,400,0); private String columnName; private boolean editable; private ColumnType columnType; private int columnWidth; private int columnIndex; private PointsTableColumns (String columnName,boolean editable,ColumnType columnType,int columnWidth,int columnIndex) { this.columnName = columnName; this.editable = editable; this.columnType = columnType; this.columnWidth = columnWidth; this.columnIndex = columnIndex; } public boolean isEditable() { return editable; } public int getColumnIndex() { return columnIndex; } public String getColumnName() { return columnName; } public int getColumnWidth() { return columnWidth; } public ColumnType getcolumnType() { return columnType; } }
我有几个这样的实现(10),每个都有多个几乎不同的值.现在,问题是我在这里看到了很多代码重复,因为所有实现中的方法都是逐字相同的.我知道在Java中这几乎是不可能的,因为枚举不能扩展实现.
我需要的是一个建议或不同的策略,可以更清洁地完成.是否已有一些关于此的现有模式?
解决方法
如果您可以使用一个级别的间接,那么我在下面介绍的方法会将重复的代码减少到最小.
首先,考虑以下供应商界面及其内部类:
public interface PropertiesSupplier { Properties properties(); public static final class Properties { private final int value1; private final String value2; private final double value3; private Properties(int value1,String value2,double value3) { this.value1 = value1; this.value2 = value2; this.value3 = value3; } public static Properties of(int value1,double value3) { return new Properties(value1,value2,value3); } public int getValue1() { return this.value1; } public String getValue2() { return this.value2; } public double getValue3() { return this.value3; } @Override public String toString() { return "Properties [value1=" + this.value1 + ",value2=" + this.value2 + ",value3=" + this.value3 + "]"; } } }
这里没什么神奇的.内部类只是一个带有私有final字段的bean,一个用于初始化它们的私有构造函数,public getter,一个工厂方法和一个覆盖toString()方法.该接口仅定义一个返回内部类实例的方法.请注意,内部类是最终的.我们的想法是强制实现不变性,以便不允许其属性发生变化.
然后,让我们创建几个将实现此接口的枚举.让我们从MyEnum1开始,它定义了两个值:
public enum MyEnum1 implements PropertiesSupplier { ENUM_1_CONST_1(Properties.of(1,"hello",0.123)),ENUM_1_CONST_2(Properties.of(2,"goodbye",7.54)); private final Properties p; private MyEnum1(Properties p) { this.p = p; } @Override public Properties properties() { return this.p; } }
接下来是MyEnum2,它只定义了一个值:
public enum MyEnum2 implements PropertiesSupplier { ENUM_2_CONST_1(Properties.of(9,"hey dude",547.21578)); private final Properties p; private MyEnum2(Properties p) { this.p = p; } @Override public Properties properties() { return this.p; } }
如您所见,两个枚举都实现了PropertiesSupplier接口,因此它们必须为Properties属性()方法提供实现.为了符合这一点,他们必须封装他们在构造函数中接收的Properties实例.
所以现在,在这个间接之后,在所有枚举中重复的唯一代码只是属性字段,接收它作为参数的构造函数及其getter方法.
这是一个展示如何使用枚举的示例:
MyEnum1 e1 = MyEnum1.ENUM_1_CONST_2; MyEnum2 e2 = MyEnum2.ENUM_2_CONST_1; System.out.println(e1.name() + " - " + e1.properties()); System.out.println(e2.name() + " - " + e2.properties());
ENUM_1_CONST_2 - Properties [value1=2,value2=goodbye,value3=7.54] ENUM_2_CONST_1 - Properties [value1=9,value2=hey dude,value3=547.21578]