Архитектура Java EE. Рекомендуется ли использовать DAO при использовании ORM, такого как JPA 2? - PullRequest
47 голосов
/ 29 сентября 2010

Если я использую ORM, такой как JPA2 - где у меня есть объекты, которые сопоставлены с моей базой данных, должен ли я по-прежнему использовать DAO? Похоже, что намного больше накладных расходов.

Например, мне нужно сохранить три дополнительных пакета:

  1. Тот, который определяет мои доменные объекты (которые в значительной степени отображают мои объекты Entity):

    public class Employee {
        private String firstName;
        private String lastName;
        ...
        // Getters and setters
    }
    
  2. Тот, который содержит интерфейсы, которые определяют мои методы DAO

    public interface EmployeeDAO {
        public void addEmployee(Employee employee);
        public Employee getEmployeeById(long id);
        ...
    }
    
  3. Тот, который содержит сессионные компоненты, которые реализуют мой DAO

    public EmployeeJpaDAO implements EmployeeDAO {
        interface method implementations here
        ....
        private method that transform my Employee entity into my Employee domain object
    }
    

Теперь нужно добавить дополнительный багаж каждый раз, когда мне нужно выполнить новую операцию CRUD.

Однако преимущества от DAO я вижу:

  1. Вы можете иметь реализацию DAO в памяти для модульного тестирования вашего уровня обслуживания. Это означает, что вам не нужен доступ к базе данных для тестирования бизнес-логики, и вы можете быть уверены, что ваши объекты всегда будут содержать одинаковые значения для свойств

  2. отделяет бизнес-логику от логики доступа к базе данных

Опция, которая не включает в себя реализацию DAO, заключается в том, чтобы просто использовать объекты сущностей и EntityManager на уровне сервиса:

@Stateless
public class EmployeeEjb {
    @PersistenceContext(unitName = "employee")
    private EntityManager manager;

    public Employee getEmployeeById(long id) {
        return manager.createNamedQuery(Employee.GetEmployeeById).getResultList();
    }
    ...
}

Здесь нет никакого среднего уровня? Кто-нибудь сталкивался с архитектурой или реализовал архитектуру, которая удовлетворяет некоторым из преимуществ уровня DAO (наиболее важно модульная тестируемость бизнес-логики), о которых я упоминал выше, но не включает все накладные расходы, связанные с реализацией уровня DAO?

Спасибо за любые рекомендации и / или предложения! Мне действительно любопытно посмотреть, что некоторые люди придумали по этому поводу.

Ответы [ 2 ]

48 голосов
/ 30 сентября 2010

Если я использую ORM, такой как JPA2 - где у меня есть сущности, которые сопоставлены с моей базой данных, должен ли я по-прежнему использовать DAO? Похоже, намного больше накладных расходов.

Это так. И, разумеется, Java EE не поощряет использование шаблона DAO при использовании JPA (JPA уже предоставляет стандартизированную реализацию шаблона Domain Store и не имеет особой ценности для его защиты за ДАО). Я считаю, что DAO в таких ситуациях против DRY .

Так что для простых случаев (на самом деле, в большинстве случаев) я с радостью пропускаю DAO, и у меня нет проблем с этим. Для более сложных случаев (например, при использовании хранимых процедур, плоских файлов) я бы использовал его. Другими словами, это зависит от того, как это обобщено в Убил ли JPA DAO? . См. Также связанные вопросы ниже:

Похожие вопросы

(...) Тот, который содержит сессионные компоненты, которые реализуют мой DAO

Нееееет, вы определенно не хотите реализовывать DAO в качестве сессионного компонента:

  • Вы не хотите создавать столько (Sooled) Session Bean, сколько таблиц (большая трата ресурсов)
  • Вы не хотите связывать Session Beans повсюду, не воспроизводите ошибок из прошлого, это известная плохая практика, которая плохо масштабируется.

Так что, если вы действительно хотите пойти по пути DAO и хотите, чтобы EM внедрялся, либо реализуйте свои DAO как Spring bean (в Java EE 5), либо как управляемый bean CDI (в Java EE 6).

У вас может быть реализация DAO в памяти для модульного тестирования уровня обслуживания.

Если вы действительно хотите провести тестирование unit , смоделируйте DAO / EntityManager, разницы нет. А если вы хотите провести интеграционное тестирование, вы можете настроить JPA на использование базы данных в памяти. Поэтому в конце я просто не покупаю этот аргумент.

отделяет бизнес-логику от логики доступа к базе данных

Честно говоря, я не вижу большой разницы между положением в DAO и менеджером сущностей, я не вижу, как DAO разделяет вещи "лучше". Опять же, я не покупаю этот аргумент.

И, по моему опыту, изменение базового решения для персистентности является очень исключительным событием, и я не собираюсь представлять DAO для чего-то, что, скорее всего, не произойдет ( YAGNI , KISS * * 1078). * * 1079

Здесь нет никакого среднего уровня? Кто-нибудь сталкивался с архитектурой или реализовал архитектуру, которая удовлетворяет некоторым из преимуществ уровня DAO (наиболее важно модульная тестируемость бизнес-логики), о которых я упоминал выше, но не включает все накладные расходы, связанные с реализацией уровня DAO?

Я не вижу среднего уровня и, как намекает я, я не использую DAO, если не чувствую в этом необходимости. И, как я уже сказал, смейтесь на EntityManager, если вы хотите по-настоящему модульного тестирования бизнес-логики. Это работает для меня, и я счастлив писать меньше кода.

Больше ресурсов

JPA / EJB3 убили DAO

DAO не мертвы - но они либо рухнули, либо исчезли ... И, наконец, вы должны ввести DAO, если:
4 голосов
/ 18 марта 2015

Для записи.

Для принципа единой ответственности (SRP), DAO является обязательным атрибутом , он разделяет модель и логику на постоянном уровне, который может быть легко переносим.

Если в проекте используется Test Unit, DAO помогает правильно его протестировать (макет, тестирование базы данных и т. Д.).

DAO - это СЕРВИС, и, как один, мы могли бы обернуть наш процесс в приятный класс, который прост в обслуживании.

JPA уменьшает количество строк кода, но, более того, старые правила по-прежнему применяются.

JPA предоставляет уровень хранилища, но его не НАШ уровень хранилища .По тому же принципу, скажем, что мы заключили в капсулу логику, которая приносит прибыль некоторому процессу.Может быть, инкапсуляция - это просто умножение на 0,1, но все же стоит инкапсулировать.

Например, допустим, у меня следующая проблема: по какой-то странной причине я могу вставить нового клиента в базу данных?,Где я должен начать тестировать?a: ClientDao, если существует, если нет, то удачи в другом месте.

...