Должны ли перечисленные объекты быть лицами без состояния? - PullRequest
6 голосов
/ 12 февраля 2009

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

Пример:

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

public enum Operation {

  DO_THIS() {
    public Result doSomething(Object theData) {
    }
  } ,
  // Other Operations go here
  ;

  public abstract Result doSomething(Object theData);

}

Теперь я хочу собрать данные о том, как часто вызывается операция и как часто она выполняется и т. Д.

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

Теперь мой общий вопрос:

Является ли экземпляр enum с сохранением состояния (помимо проблем параллелизма) плохим дизайном?

Ответы [ 8 ]

18 голосов
/ 12 февраля 2009

Я думаю, что это нарушает принцип наименьшего удивления.

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

11 голосов
/ 12 февраля 2009

Котенок умирает каждый раз, когда вы создаете изменяемое перечисление. Спаси котят!

7 голосов
/ 12 февраля 2009

Да. И под «да» я имею в виду «всегда».

Если вы хотите сопоставить статистику по числу вызванных операций, обеспечьте некоторую наблюдаемость.

4 голосов
/ 30 марта 2014

Перечисление с состоянием - это оксюморон, даже анти-шаблон!

http://en.wikipedia.org/wiki/Enumeration

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

Перечисления имеют конечное число значений, которые должны быть постоянными.

Однако тот факт, что они являются «первоклассными» объектами Java, полностью противоречит сути намерения или духу перечисления.

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

4 голосов
/ 12 февраля 2009

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

1 голос
/ 12 февраля 2009

Я полностью согласен с тем, что mparaz нарушает принцип наименьшего удивления. Люди ожидают, что перечисления будут постоянными.

Вы можете почти наверняка обойти запись, например:

DO_THIS() {
  public Result doSomething(Object theData) {
    MyUtilClass.doSomething(Object theData);
  }
}

и поместите запись в другой класс.

ОДНАКО, если вы не можете обойти это, Принцип Наименьшего Удивления является руководящим принципом; Вы можете нарушить его, ПРЕДОСТАВЛЯЯ, что вы даете пользователям класса достаточно предупреждений о том, что происходит. Убедитесь, что объявление Enum содержит БОЛЬШОЕ уведомление о том, что оно изменчиво, и точно описывает, что такое изменчивость. Enum все еще должен работать; он выполняет сравнение ссылок с одним экземпляром для проверки значений перечисления.

1 голос
/ 12 февраля 2009

Это кажется плохим использованием для перечислений - почему бы просто не использовать базовый абстрактный класс с новым подклассом для каждой операции?

0 голосов
/ 02 декабря 2015

Есть случай, который, вероятно, оправдал бы его. Enum может реализовать интерфейс, обычно с учетом конкретного случая использования, который позволяет вам создавать во время выполнения / открыто "некоторые другие типы класса enum" динамически, чтобы назвать его как-нибудь.

Это означает, что экземпляры перечисления "singleton" могут быть принудительно реализованы для реализации некоторых сигнатур методов, предназначенных для изменчивости (как сеттеров), которые, конечно, вы все еще можете скрыть с пустым кодом или NotSupportedException.

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

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