#java #design-patterns #null #null-object-pattern
#java #дизайн-шаблоны #null #нулевой объект-шаблон
Вопрос:
В нашем проекте нам нужно сохранить некоторый объект (User, например), а также класс User должен иметь флаг проверки (такие методы, как setOutdated и isOutdated)
Время от времени наш пользовательский объект может иметь значение null, но в этом случае должен быть доступен флаг проверки. Можно извлечь эти методы из пользовательского класса, но это поле и методы должны находиться внутри этого класса из-за семантики.
Я нашел несколько статей о шаблоне нулевого объекта (например, этот), и я хочу знать — возможно ли создать нулевой объект (как шаблон), который может хранить несколько состояний, таких как null устаревший, null не устаревший, not null устаревший и not null не устаревший.
PS: Если a введет «Устаревшее» поле в моем классе, будет действительно сложно очистить object вместо того, чтобы устанавливать для него значение null
Комментарии:
1. Есть ли какая-то особая причина, по которой вы не хотите проверять, является ли это значением null, прежде чем вы действительно вызовете
isOutdated()
или аналогичные «проверки состояния»?2. Даже если User равен null, у меня должен быть доступ к устаревшему полю, поэтому я должен где-то хранить эту информацию
3. В этом случае я бы просто добавил состояние, скажем, «readyToUse», для которого по умолчанию установлено значение false , и использовал объект как «не нулевой», только когда значение readyToUse равно true.
4. Что это значит для вашего приложения, когда ваш пользовательский объект равен null? Например, означает ли это «нет пользователя», или «какой-то неизвестный пользователь», или «новый пользователь»? Обычно ответ на этот вопрос поможет вам спроектировать нулевой объект.
Ответ №1:
Вы хотите различать (среди прочих) «null устаревший» и «null не устаревший».
Это означает, что вы предлагаете два разных нулевых объекта с разным поведением. Это нарушение шаблона, который гласит, что нулевой объект должен иметь один тип поведения, поведение по умолчанию для неинициализированного объекта такого типа.
Я предлагаю вам либо использовать решение, предоставленное @ Kent, либо создать свой пользовательский объект чем-то вроде объектов «PresentUser» и «FormerUser». Последнее технически является тем же решением, которое вы предлагаете сами, но это не шаблон Null Object.
Ответ №2:
Моя первая идея — добавить класс UserUtil (имя может быть каким-то другим).
и метод, подобный
public static boolean isUserOutdated(User u){
return (u==null)? true :u.isOutdated();
}
or return (u==null)? false :u.isOutdated(); depends on your businesslogic
работает ли это в вашей ситуации?
Комментарии:
1. Я боюсь использовать статические методы, потому что это кажется плохой практикой в ООП
2. я чувствую, что статические методы для класса util в порядке. Если вы действительно ненавидите статику, вы, конечно, можете удалить ‘static’ и создать подходящий конструктор. вопрос в том, работает ли это решение в моем ответе в вашей ситуации?