Логика внутри перечисления - PullRequest
9 голосов
/ 19 марта 2010

Мы с коллегами обсуждали логику в перечислениях. Лично я предпочитаю, чтобы не имели какую-либо логику в перечислениях 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;
  }
}

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

Мой аргумент был сосредоточен на разделении интересов и абстрагировании любой логики от службы. Я не думал, что «удобство» было сильным аргументом, чтобы поместить этот метод в перечисление.

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

Ответы [ 6 ]

13 голосов
/ 19 марта 2010

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

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

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

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

3 голосов
/ 19 марта 2010

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

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

2 голосов
/ 19 марта 2010

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

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

0 голосов
/ 19 марта 2010

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

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

0 голосов
/ 19 марта 2010

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

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

Мое личное мнение таково: теория практичности бродит.

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

0 голосов
/ 19 марта 2010

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

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

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

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