Расширение Java Enums - PullRequest
       1

Расширение Java Enums

5 голосов
/ 10 января 2012

У меня вопрос относительно лучшего шаблона проектирования для повторного использования кода при работе с перечислениями Java. По сути, я пытаюсь добиться определения нескольких перечислений, моделирующих статические бизнес-коллекции (наборы констант), но я также хотел бы поделиться поведением между ними с минимальным кодированием.

Это тривиально для наследования классов от абстрактных классов, но, поскольку перечисления Java не могут быть расширены (они могут реализовывать только интерфейсы), этот тип работы утомителен и включает в себя много ошибок при копировании / вставке (копирование код от перечисления к перечислению). Примеры «бизнес-логики», которая должна использоваться всеми перечислениями, включают в себя преобразование из / в строки, экземпляр и логическое сравнение и т. Д.

Мой лучший способ сейчас - использовать вспомогательные классы в сочетании с бизнес-интерфейсами, но это только доходит до снижения сложности кода (поскольку все перечисления все еще должны объявлять и вызывать вспомогательные классы). Смотрите пример (просто чтобы уточнить):

public enum MyEnum {
    A, B, C;

    // Just about any method fits the description - equals() is a mere example
    public boolean equals(MyEnum that) {
        ObjectUtils.equals(this, that);
    }
} 

Как StackOverflowers справляется с этой "языковой функцией"?

Ответы [ 4 ]

3 голосов
/ 10 января 2012

Вы можете переместить многократно используемую логику в выделенные (не перечисляемые) классы, а затем делегировать перечисления этим классам.Вот пример:

[Примечание: наследование PlusTwo extends PlusOne не рекомендуется (b / c PlusTwo не PlusOne).Это здесь просто для иллюстрации смысла расширения существующей логики.]

public interface Logic {
  public int calc(int n);
}

public static class PlusOne implements Logic {
  public int calc(int n) { return n + 1; }
}

public static class PlusTwo extends PlusOne {
  @Override
  public int calc(int n) { return super.calc(n) + 1; }
}

public static enum X {
  X1, X2;   
  public Logic logic;

  public int doSomething() { 
    return logic.calc(10);
  }
}

public static enum Y {
  Y1, Y2;
  public Logic logic;

  public String doSomethingElse() { 
    return "Your result is '" + logic.calc(10) + "'";
  }
}

public static void main(String[] args) {
  // One time setup of your logic:
  X.X1.logic = new PlusOne();
  X.X2.logic = new PlusTwo();  
  Y.Y1.logic = new PlusOne();
  Y.Y2.logic = new PlusTwo();

  System.out.println(X.X1.doSomething());
  System.out.println(X.X2.doSomething());
  System.out.println(Y.Y1.doSomethingElse());
  System.out.println(Y.Y2.doSomethingElse());
}
2 голосов
/ 10 января 2012

Я редко нахожу enums полезным, за исключением представления конечных состояний, в этом случае им не нужно поведение.

Я бы предложил рефакторинг enums, которому нужно поведение, в classes с Factory.

2 голосов
/ 10 января 2012

Я бы сделал то же самое или объединил бы Enums в супер-перечисление.

С Java 8 это будет проще. Вы сможете определить реализацию default для методов интерфейса, а enum расширить интерфейс.

0 голосов
/ 10 января 2012

Это может показаться немного уродливым, но обычно может предложить вам необходимую функциональность.

У вас может быть интерфейс

public interface MyEnumInterface<T extends Enum<T>> {

    String getBusinessName();

    T getEnum();

}

Реализация

public enum OneOfMyEnums implements MyEnumInterface<OneOfMyEnums>{

    X, Y, Z;

    @Override
    public String getBusinessName() {
        return "[OneOfMyEnums]" + name();
    }

    @Override
    public OneOfMyEnums getEnum() {
        return this;
    }

}

И утилитакласс вместо вашего родительского класса

public class MyEnumUtils {

    public static <T extends Enum<T>> String doSomething(MyEnumInterface<T> e){
        e.getBusinessName(); // can use MyEnumInterface methods
        e.getEnum().name(); // can use Enum methods as well
        return null;
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...