枚举中的代码重复继承了一个通用接口 [英] Code duplication in enums inheriting a common interface

查看:112
本文介绍了枚举中的代码重复继承了一个通用接口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有几个符合常用界面的枚举:

 界面TableColumns 
{
String getColumnName()所;
int getColumnIndex();
ColumnType getColumnType();
boolean isEditable();
int getColumnWidth();
}

典型的实现是:

 枚举PointsTableColumns实现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();

public static final class Properties {

private final int value1;

private final String value2;

private final double value3;

private属性(int value1,String value2,double value3){
this.value1 = value1;
this.value2 = value2;
this.value3 = value3;
}

public static(int value1,String value2,double value3)的属性{
返回新属性(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(){
returnProperties [value1 =+ this.value1 +,value2 =+ this.value2 +,value3 =+ this.value3
+];
}
}
}

内部类只是一个具有 private final 字段的bean,一个用于初始化它们的私有构造函数,public getter,一个工厂方法和一个覆盖 toString() 方法。该接口仅定义一个返回内部类的实例的方法。请注意,内部类是final。这个想法是强制执行不变性,以使其属性不被更改。



然后,我们来创建一些将实现此接口的枚举。我们从 MyEnum1 开始,它定义了两个值:

  public enum MyEnum1实现PropertiesSupplier {
ENUM_1_CONST_1(Properties.of(1,hello,0.123)),
ENUM_1_CONST_2(Properties.of(2,再见,7.54));

private final属性p;

私人MyEnum1(属性p){
this.p = p;
}

@Override
public属性属性(){
return this.p;
}
}

接下来是 MyEnum2 ,它仅定义一个值:

  public enum MyEnum2实现PropertiesSupplier {
ENUM_2_CONST_1(属性) (9,嘿兄弟,547.21578));

private final属性p;

私人MyEnum2(属性p){
this.p = p;
}

@Override
public属性属性(){
return this.p;
}
}

如你所见,这两个枚举都实现了 PropertiesSupplier 接口,所以他们必须为 Properties properties()方法提供一个实现。为了遵守这一点,他们必须封装一个属性的实例,它们在构造函数中收到。



所以现在,在这个间接方法之后,所有枚举中唯一重复的代码只是属性字段,接收它作为参数的构造函数及其getter方法。 / p>

这是一个示例,显示如何使用枚举:

  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  - 属性[value1 = 2,value2 =再见,value3 = 7.54] 
ENUM_2_CONST_1 - 属性[value1 = 9,value2 = hey dude,value3 = 547.21578]


I have several enums which comply to a common interface:

    interface TableColumns
    {
      String getColumnName();
      int getColumnIndex();
      ColumnType getColumnType();
      boolean isEditable();
      int getColumnWidth();
    }

A typical implementation is:

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;
    }
}

I have several implementaions like this (10+), each having multiple and almost different values. Now, the problem is that I see a lot of code duplication here, as the methods in all of the implementation are identical word by word. I know that in Java this is virtually impossible as enums can't extend an implementation. What I need here is a suggestion or a different strategy where this can be done in a cleaner way. Is there already some existing pattern regarding this?

解决方案

If you can live with one level of indirection, then the approach I present below will reduce repeated code to a minimum.

First, consider the following supplier interface, along with its inner class:

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, String value2, 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
                    + "]";
        }
    }
}

Nothing magic here. The inner class is just a bean with private final fields, a private constructor to initialize them, public getters, a factory method and an overriden toString() method. The interface defines only one method that returns an instance of the inner class. Note that the inner class is final. The idea is to enforce immutability, so that its properties are not allowed to change.

Then, let's create a couple of enums that will implement this interface. Let's start by MyEnum1, which defines two values:

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;
    }
}

Next comes MyEnum2, which defines only one value:

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;
    }
}

As you see, both enums implement the PropertiesSupplier interface, so they must provide an implementation for the Properties properties() method. And in order to comply with this, they must encapsulate an instance of Properties, which they receive in their constructor.

So now, after this indirection, the only code that is repeated among all enums is just the Properties field, the constructor that receives it as an argument and its getter method.

This is a sample showing how the enums would be used:

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());

This code produces the following output

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]

这篇关于枚举中的代码重复继承了一个通用接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆