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

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

11 голосов
/ 14 апреля 2010

Допустим, я решил использовать стек Java EE для своего корпоративного приложения.

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

Например,

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

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

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

Ответы [ 2 ]

8 голосов
/ 14 апреля 2010

Вот что я считаю традиционным взглядом:

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

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

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

  • Сущности -> POJO с аннотациями Hibernate / JPA. Обратите внимание, что аннотации не предполагают тесной связи с JPA / Hibernate, тот же POJO может использоваться где-то еще без Hibernate.
  • Бизнес-уровень -> Сеанс 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, то вашему уровню данных необходимо удалить abstract Hibernate / JPA. Если вы используете DAO для своего уровня данных, это будет иметь место. DAO будет «тонким рукописным постоянным слоем над Hibernate» (если принять ваши слова). Я бы представил DAO для всех организаций в вашем случае.

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

Тем не менее, вот список ресурсов, которые могут вас заинтересовать: книги Шаблон архитектуры корпоративных приложений , книга Шаблоны реального мира Java EE - переосмысление передового опыта , книга Домен-управляемый дизайн и, в частности, шаблоны Объект доступа к данным , Шаблон репозитория , Открыть сеанс в представлении (если это для веб-приложение) и, возможно, Модель анемичного домена .

РЕДАКТИРОВАТЬ 2

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

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

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

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

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

4 голосов
/ 14 апреля 2010

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

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

...