Как смоделировать в Java EE?

Скажем, я решил пойти со стеком Java EE для моего корпоративного приложения.

Теперь, для моделирования домена (или: для разработки M MVC), какие API я могу безопасно принять и использовать, и которого я должен избегать..., говорят, через слой абстракции?

Например,

  1. Я должен идти вперед и замусорить свою Модель вызовами к API Hibernate/JPA? Или, я должен создать абстракцию... мой собственный слой персистентности для предотвращения жесткого кодирования против этих двух определенных API персистентности? Почему я спрашиваю это: Несколько лет назад был этот API Kodo, который был заменен, в спящем режиме. Если бы каждый разработал слой персистентности и кодировал остальную часть модели против этого слоя (вместо того, чтобы замусорить Модель вызовами определенному поставщику API), то это позволит тому (относительно) легко переключателю от Kodo Быть в спящем режиме к xyz.

  2. Рекомендуется сделать агрессивное использование *QL обеспеченный Вашим поставщиком персистентности в Вашей модели предметной области? Я не знаю ни о каких реальных проблемах (как производительность, масштабируемость, мобильность, и т.д.) проистекать из интенсивного использования подобного HQL языка. Почему я спрашиваю это: Я хотел бы избежать, как можно больше, пишущий пользовательский код, когда то же могло быть выполнено через язык запросов, который является более портативным, чем SQL.

Извините, но я - полный новичок к этой области. Где я мог найти больше информации об этой теме?

11
задан Arjan Tijms 25 February 2013 в 20:03
поделиться

2 ответа

Вот что я считаю традиционной точкой зрения:

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

Сущность не должна напрямую обращаться к уровню доступа к данным. Но бизнес-слой будет это делать, загружая и сохраняя сущности доменной модели.

Если сопоставить это с технологиями Java EE, то обычно получается что-то вроде:

  • Entities --> POJO с аннотациями Hibernate/JPA. Обратите внимание, что аннотации не означают тесную связь с JPA/Hibernate, тот же самый POJO может быть использован в другом месте без Hibernate.
  • Бизнес-слой --> Session EJB или Spring
  • Уровень доступа к данным --> JPA/Hibernate

Это грубый набросок, и существует множество возможных вариантов. Вы можете, конечно, пропустить сессионный EJB и реализовать бизнес-слой другим способом. Вы также можете решить, чтобы бизнес-слой вызывал JPA/Hibernate Session/EntityManager напрямую, в этом случае JPA/Hibernate действительно является DAL, или вы можете захотеть обернуть доступ к Session/EntityManager в так называемые объекты доступа к данным (DAO).

Что касается HQL, старайтесь придерживаться того, что переносимо, и если вы используете родной SQL, следуйте соглашениям SQL-92. Если вещи становятся сложными, возможно, стоит ввести DAO. Таким образом, вы будете знать, что единственное место, где есть HQL-запросы, находится в DAO. Вы также можете сначала реализовать логику запроса "процедурно" в DAO, и если у вас возникнут проблемы с производительностью, перереализовать ее с помощью более сложного HQL-запроса.

EDIT

По поводу ваших вопросов в комментарии:

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

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

Тем не менее, вот список ресурсов, которые могут вас заинтересовать: книги Pattern of Enterprise Application Architecture, книга Real World Java EE Patterns - Rethinking Best Practices, книга Domain Driven Design и более конкретно паттерны Data Access Object, Repository pattern, Open Session in View (если это для веб-приложения), и, возможно, Anemic Domain Model.

EDIT 2

Хорошо, еще несколько предложений о транзакциях:

Концептуально транзакции должны управляться на бизнес-слое; определение того, что должно быть сделано в одной единице работы, чтобы быть последовательным, действительно зависит от самой логики приложения.

В EJB3 транзакции могут быть объявлены с помощью аннотаций, и сервер приложений управляет этим за вас. См. этот другой мой ответ для получения дополнительной информации. В Spring вы также можете объявлять транзакции декларативно, но я не знаю деталей. В противном случае вам придется запускать/останавливать транзакцию самостоятельно. Это будет немного отличаться от того, используете ли вы транзакции JDBC или транзакции JTA.

Транзакции также связаны с ленивой загрузкой в Hibernate/JPA. Сущность, которая была лениво загружена, действительно может быть загружена только при наличии текущей транзакции. Если транзакция завершается на бизнес уровне, сущности, которые возвращаются на презентационный уровень, должны быть загружены с нетерпением.

Чтобы обойти эту проблему, популярным паттерном для веб-приложений является Open Session in View, о котором я уже упоминал. В этом случае презентационный слой запускает/останавливает транзакции (что немного неправильно концептуально), но прекрасно работает с ленивой загрузкой.

8
ответ дан 3 December 2019 в 09:19
поделиться

Ваша модель предметной области и ее уровень сохраняемости теоретически должны быть разделены - нет необходимости в классе с именем Entity , чтобы знать что-либо о том, если и как он сохраняется, поэтому вы можете использовать что-то вроде Hibernate для создания уровня постоянства, не загрязняя сами классы модели предметной области. Вы не «кодируете [...] модель для этого уровня» - вы кодируете модель, а затем сопоставляете ее с постоянным хранилищем с каким-то уровнем ORM, где модель предметной области не зависит от уровня ORM. Очевидно, что уровень сохраняемости будет зависеть от модели предметной области, но это нормально.

Я лично боюсь использовать слишком много HQL с (N) Hibernate по той причине, о которой вы спрашиваете, но бывают случаи, когда это неизбежно. Вы уже знаете и выделили основную проблему, так что вряд ли вы в любом случае будете злоупотреблять ею.

4
ответ дан 3 December 2019 в 09:19
поделиться
Другие вопросы по тегам:

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