Статьи

DAO — еще один ООП позор

Кто-то спросил меня, что я думаю о DAO, и я понял, что, хотя я писал об ORM , DTO и добытчиках , у меня еще не было возможности упомянуть DAO. Вот мое мнение: это такой же позор, как и его друзья — ORM, DTO и добытчики. В двух словах, объект доступа к данным — это объект, который «предоставляет абстрактный интерфейс для некоторого типа базы данных или другого механизма персистентности». Цель благородна, но реализация ужасна.

Реквием по мечте (2000) Даррен Аронофски

Вот как это может выглядеть :

1
2
3
4
5
class BookDAO {
  Book find(int id);
  void update(Book book);
  // Other methods here ...
}

Идея проста — метод find() создает Book DTO , кто-то другой вводит в нее новые данные и вызывает update() :

1
2
3
4
BookDAO dao = BookDAOFactory.getBookDAO();
Book book = dao.find(123);
book.setTitle("Don Quixote");
dao.update(book);

Вы спрашиваете, что не так? Все, что было не так с ORM , но вместо «сессии» у нас есть этот DAO. Проблема остается той же: book не объект, а контейнер данных. Я цитирую свое собственное трехлетнее утверждение из статьи ORM с небольшим изменением названия: «DAO вместо инкапсуляции взаимодействия с базой данных внутри объекта извлекает его, буквально разрывая прочный и сплоченный живой организм». Для более подробной информации, пожалуйста, проверьте эту статью.

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

1
2
3
4
interface Pipes {
  void add(String json);
  Pipe pipe(long number);
}

Его метод add() создает новый элемент в «коллекции», а метод pipe() возвращает один объект из коллекции. Канал не DTO, это обычный объект, который полностью способен выполнять все необходимые операции с базой данных без помощи DAO. Например, есть Pipe.status(String) для обновления его статуса. Я не собираюсь использовать Pipes для этого, я просто делаю pipe.status("Hello, world!) .

Вот еще один пример из Jare.io : интерфейс Base который возвращает список объектов типа Domain . Затем, когда мы хотим удалить домен, мы просто вызываем domain.delete() . Домен полностью способен выполнять все необходимые манипуляции с базой данных.

Я считаю, что проблема с DAO прямо в ее названии. В нем говорится, что мы обращаемся к «данным» и делаем именно это: заходим в базу данных, извлекаем некоторые данные и возвращаем данные . Не объект, а данные, также известные как «объект передачи данных». Как мы уже говорили , прямые манипуляции с данными — это то, что нарушает инкапсуляцию и делает объектно-ориентированный код процедурным и не поддерживаемым.

Опубликовано на Java Code Geeks с разрешения Егора Бугаенко, партнера нашей программы JCG . Смотрите оригинальную статью здесь: DAO — еще один позор ООП

Мнения, высказанные участниками Java Code Geeks, являются их собственными.