Логика в перечислении

У моих коллег и меня было обсуждение относительно логики в перечислениях. Мое персональное предпочтение не состоит в том, чтобы иметь никакого вида логики в перечислениях Java (хотя Java обеспечивает способность сделать это). Обсуждение в этом случилось центрируемый вокруг наличия удобного метода в перечислении, которое возвратило карту:

public enum PackageType {
  Letter("01", "Letter"),
  ..
  ..
  Tube("02", "Packaging Tube");

  private String packageCode;
  private String packageDescription;

  ..
  ..

  public static Map<String, String> toMap() {
     Map<String, String> map = new LinkedHashMap<String, String>();
     for(PackageType packageType : PackageType.values()) {
         map.put(packageType.getPackageCode(), packageType.getPackageDescription());
     }
     return map;
  }
}

Мое персональное предпочтение состоит в том, чтобы вытащить это на службу. Аргумент в пользу того, чтобы иметь метод в перечислении, центрируемом вокруг удобства. Идея состояла в том, что Вы не должны переходить к службе для получения его, но можете запросить перечисление непосредственно.

Мой аргумент, центрируемый вокруг разделения беспокойства и абстрагирующий любой вид логики к сервису. Я не думал, что "удобство" было веским доводом для помещения этого метода в перечислении.

С точки зрения лучших практик, какой лучше? Или это просто сводится к вопросу персонального предпочтения и стиля кода?

9
задан Vivin Paliath 19 March 2010 в 00:07
поделиться

6 ответов

Что ж, я делал это раньше, но это, конечно, не значит, что это «лучший» поступок.

Однако, с моей точки зрения, я бы предпочел иметь эту логику в перечислении по той же причине, по которой вы не переместите метод toString в службу. Логика касается только самого перечисления и его собственного представления.

Я думаю, что было бы ошибкой переносить такой метод в службу - помещая его в перечисление, вы заранее заявляете о том, что перечисление имеет метод toMap. Кто-то, кто не знал об услуге и просто смотрел на enum, может этого не знать.

Это также помогает с автоматическим завершением в IDE - я могу нажать "." key и мгновенно увидеть методы, предоставляемые объектом.

14
ответ дан 4 December 2019 в 11:04
поделиться

Я думаю, что это, вероятно, сводится к личным предпочтениям и тому, думаешь ли ты, что логика может измениться в будущем.

Лучше всего использовать логику перечисления (поскольку она довольно статична) для вещей, которые не собираются меняться. Логика в java.util.concurrent.TimeUnit является довольно хорошим примером: коэффициенты преобразования между единицами времени четко определены и никогда не изменятся, так что это хороший кандидат для статической логики. встроен в перечисление.

3
ответ дан 4 December 2019 в 11:04
поделиться

Я бы начал с помещения его в перечисление. Если в системе будет только один метод toMap (), наличие дополнительного класса, безусловно, излишне и будет раздражать.

Если бы у меня была куча перечислений, из которых я хочу создать такую ​​карту или, возможно, предвидеть такую ​​ситуацию, ТОГДА я создам статический служебный класс и обобщенный служебный метод для этого.

Мое личное мнение, практичность бродит по теории.

РЕДАКТИРОВАТЬ: Ой, подождите, было бы сложно предоставить универсальный служебный метод для .. В этом случае, если метод будет специфичным для этого перечисления, я бы определенно пошел и поместил его в перечисление. Если бы я был программистом по обслуживанию, я был бы очень недоволен, если бы у вас был дополнительный класс, который мне пришлось бы искать.

0
ответ дан 4 December 2019 в 11:04
поделиться

Как и все остальное, это зависит от использования, есть общие правила, но практичность всегда должна побеждать в споре. Для чего используется карта? Нужно ли вам когда-нибудь ограничить содержимое карты, например, если карта используется для заполнения комбинированного поля, есть ли необходимость удалить некоторые варианты, скажем, если некоторые перевозчики работают только с определенными типами пакетов, можно использовать стратегию для заполнения карты, что лучше всего сделать вне перечисления.

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

0
ответ дан 4 December 2019 в 11:04
поделиться

Я несколько раз пробовал логику в перечислениях, но единственное, что меня действительно радует, это что-то вроде:

// not compiled, so might have errors...
public enum Foo
{
   A,
   B;

   // not complete, doesn't properly handle invalid cases...
   public static Foo fromString(final String str)
   {
       final String strLower;
       final Foo    val;

       strLower = str.toLowerCase();

       if(strLower.equals("a")
       {
           val = A;
       }
       else if(strLower.equals("b")
       {
           val = B;
       }
       else
       {
           throw new IllegalArgumentException(/*...*/);
       }

       return (val);
   }
}

Вообще, как только вы начинаете добавлять переменные/методы экземпляра, вы, вероятно, должны делать что-то с помощью соответствующего класса.

0
ответ дан 4 December 2019 в 11:04
поделиться

Я не вижу убедительной причины, почему это "хорошая практика" ... или "плохая практика" ... делать то, что вы предлагаете.

Я склоняюсь к аргументу удобства. Но, честно говоря, это не та вещь, на которую продуктивно тратить человеко-дни на обсуждение ... ИМО.

2
ответ дан 4 December 2019 в 11:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: