Подтвердить что ты не робот

Должно ли вы определить нулевое/неизвестное значение для перечислений Java?

Когда вы определяете перечисление для того, что может быть "undefined" в ваших интерфейсах, вы должны

  • определите для него отдельное значение перечисления или
  • просто используйте enumValue = null для этих ситуаций?

Например,

serviceX.setPrice(Цена priceEnum)

enum Price {
 CHEAP, EXPENSIVE, VERRRY_EXPENSIVE, UNKNOWN
}

и priceEnum.UNKNOWN при необходимости

или

enum Price {
 CHEAP, EXPENSIVE, VERRRY_EXPENSIVE
}

и priceEnum = null при необходимости?

Немного спорить об этом. Некоторые моменты, которые приходят на ум:

  • с помощью Price.UNKNOWN сохраняет код "if (price == null)". Вы можете обрабатывать Price x все значения в одном коммутационном футляре
  • В зависимости от технологии просмотра может быть проще локализовать Price.UNKNOWN
  • используя метод Price.UNKNOWN причины "магического номера" в коде, IMO. Здесь у нас есть Price.UNKNOWN, в другом месте, возможно, Color.UNDEFINED, Height.NULLVALUE и т.д.
  • using priceValue = null более равномерен с тем, как обрабатываются другие типы данных в Java. Мы имеем Integer я = null, DomainObject x = null, String s = null для неизвестных значений, не так ли?
  • Price.UNKNOWN заставляет вас решить, разрешено ли null-значение для всех случаев использования. У нас может быть метод Price getPrice(), который может возвращать Price.UNKNOWN и setPrice (Цена p), которым запрещено принимать Price.UNKNOWN. Поскольку Price.UNKNOWN всегда включен в значения перечисления, эти интерфейсы выглядят немного нечистыми. Я знаю, что priceValue = null имеет ту же проблему (вы не можете определить в интерфейсе, принимается ли null или нет), но он чувствует себя немного чище и немного менее вводит в заблуждение (?)
4b9b3361

Ответ 1

Это на самом деле пример применения Null Object pattern. ИМХО всегда лучше иметь фиктивный объект, а не нуль. Например, вы можете добавлять фиктивные методы к нулевому объекту, а не разбрасывать свой код с нулевыми проверками повсюду. Очень удобно.

Также имя enum дает вам дополнительную семантику: неизвестна ли цена, undefined, не заслуживает доверия, еще не известна? И что это означает, если цена равна нулю?

ОБНОВЛЕНИЕ: Как указывает Аарон Дигулла, для шаблона Null Object требуется память. Но в большинстве случаев это не так. В традиционной реализации вы обычно используете singleton для объекта Null, который используется везде, так как нет необходимости в отдельных экземплярах. Он становится еще лучше с перечислениями, потому что вы получаете семантику singleton бесплатно.

Другим моментом является то, что ссылка null и ссылка на некоторый объект занимают тот же объем памяти (скажем, 4 байта на 32-битной машине). Это ссылка на объект, который занимает некоторую дополнительную память. Но если это синглтон, здесь накладных расходов практически нет.

Ответ 2

Я бы сказал, идите с Price.UNKNOWN, если это допустимое значение для цены.

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

Новые языки, возьмите Scala, например (и некоторые более старые, Haskell), отделяйте от нулевых ссылок все вместе и вместо этого используйте опцию/возможно монады... по уважительным причинам.

Ответ 3

Это зависит от того, как вы собираетесь использовать это перечисление. Если вы используете его в операторах switch/case, это не имеет значения. Если вы создадите метод в перечисление, вы должны действительно определить UNKNOWN.

Например, вы можете определить абстрактный метод public abstract Icon icon();

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

Ответ 4

Существует Enum-Switch-Null-Trap. Таким образом, похоже, что как с любым свойством, являющимся объектом, если он не существует, то он null.

Ответ 5

Цвет или высота будут использоваться в логике программы. Они не могут обрабатывать цвет undefined. Цена - это userdata и может быть неизвестна. Цвет может быть userdata else, но для использования в качестве цвета в коде они должны быть определены.

Итак, цена может быть UNKNOWN (вместо null), Color not (null может указывать на ошибку).