Сервисный уровень против DAO - Почему оба?

64

Я работал с SpringMVC, Hibernate и некоторыми базами данных в примере с веб-приложением Java.

Есть несколько разных, которые делают это, но в этом руководстве по интеграции с Spring 3 и hibernate с примером есть класс модели, представление (в jsp), а также классы обслуживания и dao для контроллера.

Мой вопрос: разве классы обслуживания и DAO не делают одно и то же? Зачем вам они оба?

Это было учебное пособие, которое я фактически использовал: http://fruzenshtein.com/spring-mvc-security-mysql-hibernate/

Джефф
источник

Ответы:

60

Как правило, DAO настолько легок, насколько это возможно, и существует исключительно для обеспечения соединения с БД, иногда абстрагированной, поэтому можно использовать разные бэкэнды БД.

Сервисный уровень предназначен для обеспечения логики работы с данными, отправляемыми в DAO и из клиента. Очень часто эти 2 компонента объединяются в один и тот же модуль, а иногда и в один и тот же код, но вы все равно увидите их как отдельные логические объекты.

Другая причина - безопасность. Если вы предоставляете сервисный уровень, который не имеет отношения к БД, то будет сложнее получить доступ к БД от клиента, кроме как через сервис. Если к БД невозможно получить доступ напрямую с клиента (и нет тривиального модуля DAO, выступающего в качестве службы), то все, что может сделать злоумышленник, захвативший клиента, - это попытаться взломать уровень обслуживания, прежде чем он получит все, кроме наиболее обеззараженный доступ к вашим данным.

gbjbaanb
источник
1
Я согласен с разделением уровней обслуживания и дао и уровня обслуживания, содержащего вашу бизнес-логику.
Питер Делани
не говоря уже о том, что одна служба может вызывать несколько DAO, например, при сохранении пользователя вы можете поговорить с UserDao, UserOrdersDao и т. д. Или мы должны создать одну службу для каждой? И кто тогда мог назвать все эти услуги?
Фермин Сильва
40

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

Кроме того, весной безопасность применяется на уровне обслуживания в идеале. Вы не хотели бы изменить этот путь.

Lokesh
источник
5
Эй, большое спасибо за ответ на мой вопрос; это преданность вашему блогу! Спасибо за отличный пример, продолжайте писать.
Джефф
Некоторое время это мешало мне, и я думаю, что опыт помогает в таких ситуациях больше всего. Спасибо.
Утку Оздемир,
Я согласен с разделением уровней обслуживания и дао и уровня обслуживания, содержащего вашу бизнес-логику, и буду вызывать только методы Дао. Как насчет того, когда один из моих методов обслуживания должен вызывать другой метод обслуживания. Должен ли я иметь другую абстракцию над уровнем службы, которая вызывает несколько методов службы?
Питер Делани
Нет. Классы на сервисном уровне могут иметь ссылку друг на друга (при необходимости) и могут вызывать требуемые методы.
lokesh
11

Адам Бьен в своей книге указывает на тот факт, что JPA EntityManager является хорошей универсальной реализацией DAO:

http://realworldpatterns.com/

В мире Java EE почти никогда не нужно писать свой собственный DAO, потому что реализации JPA включают его. Вам нужно только написать сервисный слой.

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

Итак, чтобы ответить на ваш вопрос, да, вам нужен сервисный уровень и DAO, но вам нужно только написать сервисный уровень.

Декан шульце
источник
2
Я не уверен, относится ли это к Spring - всегда есть специальный DAO, который нужно сделать для модели. Может быть, ваше утверждение «почти никогда не нужно писать свой собственный DAO» относится конкретно к EJB-контейнерам / серверу приложений?
Дон Чидл
1
Лучше написать свой собственный (DAO / DAOImpl), хотя он будет отображаться только в EntityManager - это потому, что в будущем вы можете добавить еще одну реализацию DAO без необходимости изменения кода уровня обслуживания .
ahmednabil88
@YajliMaclo какая разница что менять?
Alex78191
4

Я обычно помещаю весь специфический для БД код (запросы) в DAO, обработку транзакций и бизнес-логику в сервисы. Это позволяет сервисным методам вызывать методы из нескольких дао и хранить их в одной транзакции. На мой взгляд, это позволяет лучше повторно использовать код в Дао.

sbrattla
источник
2

Я обнаружил, что уровень обслуживания добавляет ненужную сложность в большинстве случаев. Теоретически - избегать бизнес-логики в слое dao, но в конце это просто приводит к путанице, даже некоторые люди отказались полностью удалить слой dao, так как считают, что он не добавляет ценности. http://ayende.com/blog/4784/architecting-in-the-pit-of-doom-the-evils-of-the-repository-abstraction-layer

Но если у вас несколько бизнес-логик, тогда да. Это хорошая идея. Насколько важно сделать уровень обслуживания?

Иисус
источник
3
Я читал пост в блоге Айенде уже несколько раз, и просто не могу избавиться от ощущения, что его дизайн (с которым я бы согласился в какой-то момент), хотя и соответствует духу YAGNI, почти неизбежно будет стоить больше времени для разработки даже в Среднесрочный, чем это стоило бы установить абстракцию слоев в первую очередь. Интересно, изменил ли он свое мнение о тесной связи между всем приложением и NHibernate сейчас, когда одному приложению еще чаще приходится запрашивать несколько источников данных SQL, NoSQL и API.
Мистер Кочезе
@LennyGodber да, я знаю, что вы чувствуете, что у IMO лучше иметь слой DAO / репозитория, потому что он имеет больше преимуществ и недостатков, потому что, как вы говорили, очень часто иметь несколько источников данных
Иисус
-1

ИМХО Сервисный уровень можно рассматривать как уровень между контроллером и уровнем DAO. Этот сервисный слой именно там, где мы можем добавить бизнес-логику и даже создать объект возврата, специфичный для того, что должно быть отображено представлением.

compserve23
источник