DAO с шаблоном нулевого объекта
После прочтения:
Эффективная Ява (см. Пункт 43) - Джошуа Блох
Чистый код (не возвращать ноль) - дядя Боб
Избегать!= Нулевые заявления
Нулевой объект
Я искал ответ на вопрос о том, что DAO должен возвращать, когда поиск заканчивается для объекта, который не существует для объектов, не являющихся коллекцией. Объект коллекции действительно в порядке, используя пустой массив или методы emptyList. Но с не коллекциями это может быть сложнее. Альтернативное решение состоит в том, чтобы никогда не возвращать нуль и вместо этого использовать шаблон Null Object. Но я понятия не имею, что интегрировать с шаблоном Null Object с DAO, и я действительно рад видеть отличную интеграцию с шаблоном Null Object и шаблоном DAO, особенно для случая возврата объекта модели (dto).
Буду признателен за любую лучшую модель дизайна, сценарий и предложение.
3 ответа
Действительно представляя null
Ссылка, вероятно, является одной из худших ошибок в истории языков программирования, даже ее создатель Тони Хоар называет это своей ошибкой в миллиард долларов.
Вот лучшие альтернативы null
в соответствии с вашими Java
версия:
1. Java 8
и выше
Начиная с Java 8 вы можете использовать java.util.Optional
,
Вот пример того, как вы могли бы использовать его в вашем случае:
public Optional<MyEntity> findMyEntity() {
MyEntity entity = // some query here
return Optional.ofNullable(entity);
}
2. До Java 8
До Java 8 вы можете использовать com.google.common.base.Optional
из Google Guava.
Вот пример того, как вы могли бы использовать его в вашем случае:
public Optional<MyEntity> findMyEntity() {
MyEntity entity = // some query here
return Optional.fromNullable(entity);
}
Все, что вам нужно сделать, это вернуть пустой объект - скажем, запись клиента, которая у вас будет в вашем DAO, примерно такая:
if (result == null) { return new EmptyUser(); }
где EmptyUser расширяет User и возвращает соответствующие записи для вызовов getter, чтобы остальная часть вашего кода знала, что это пустой объект (id = -1 и т. д.)
Маленький пример
public class User {
private int id;
private String name;
private String gender;
public String getName() {
//Code here
}
public void setName() {
//Code here
}
}
public class EmptyUser extends User {
public int getId() {
return -1;
}
public String getName() {
return String.Empty();
}
}
public User getEntry() {
User result = db.query("select from users where id = 1");
if(result == null) {
return new EmptyUser();
}
else {
return result;
}
}
По моему опыту, в реальных сценариях, в которых должен быть возвращен один объект, возвращающий ноль, фактически является либо ошибкой несогласованности данных, либо отсутствием данных. В обоих случаях действительно хорошая вещь, чтобы сделать ящик и бросить свой собственный DataNotFoudException
, Сбой быстро.
Я использую mybatis в качестве ORM, и недавно я начал писать некоторые теоретически мапперы с одиночным результатом как возвращающие списки и проверяющие проверку количества возвращаемых данных в dao и выдачу исключений, когда возвращаемые суммы не соответствуют предположениям метода dao. Это работает довольно хорошо.