Java – duplicate code in enumeration inheriting public interface

I have several enumerations that conform to common interfaces:

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

Typical implementations are:

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 such implementations (10), each with multiple almost different values Now, the problem is that I see a lot of code duplication here, because the methods in all implementations are the same word for word I know this is almost impossible in Java because enumeration cannot extend the implementation What I need is a suggestion or a different strategy that can be done more cleanly Are there any existing patterns for this?

Solution

If you can use a level of indirection, the methods I describe below will minimize duplicate code

First, consider the following supplier interfaces and their internal classes:

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

There's nothing magical here The inner class is just a bean with a private final field, a private constructor used to initialize them, a public getter, a factory method and an override toString () method This interface defines only one method that returns an internal class instance Note that inner classes are final The idea is to enforce invariance so that its properties are not allowed to change

Then, let's create several enumerations that will implement this interface Let's start with 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 is 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 can see, both enumerations implement the propertiessupplier interface, so they must provide an implementation for the properties property () method To meet this, they must encapsulate the properties instance they receive in the constructor

So now, after this indirection, the only code that repeats in all enumerations is the property field, the constructor that receives it as a parameter, and its getter method

This is an example showing how to use enumeration:

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 generates 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]
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>