Как правильно использовать Struts ActionForms, Value Objects и Entities? - PullRequest
3 голосов
/ 03 октября 2008

Я унаследовал большое Java-приложение, которое использует Struts, Spring и Hibernate. Классы и интерфейсы, с которыми я работаю ежедневно: Действия Struts, Формы действий Struts, Объекты значений, Интерфейсы и реализации служб, Интерфейсы и реализации DAO и Объекты. Я довольно ясно понимаю, как и почему большинство из них, за исключением того, что я не уверен в правильном разделении обязанностей между ActionForms, Value Objects и Entities. Я должен также упомянуть, что Модель предметной области (то есть все сущности) не содержит много (если таковые имеются) реальной бизнес-логики. По сути, это приложение CRUD, и большая часть реальной логики находится в базе данных (чёрт!). В любом случае, есть несколько различных проблем, связанных с Java:

1) Кажется, что между сущностями и объектами-значениями (VO) не так много различий, и нужно написать много кода для преобразования в другое, когда они проходят через уровень обслуживания в любом направлении (действия Struts имеют дело только с VO, DAO имеют дело только с Entities). Итак, ВО и организации кажутся несколько избыточными. Почему они оба?

2) Куда должен идти код перевода VO <-> Entity? Служебный уровень, Сущность, ВО?

3) VO помещаются непосредственно в ActionForms и напрямую связаны с тегами в JSP (например,). Это хорошая практика? Если нет, каков соответствующий дизайн?

4) Неясно, как правильно обрабатывать зависимости внешнего ключа в объектах значений. Например, некоторые VO имеют поле типа, которое в терминах базы данных представляет отношение внешнего ключа в таблице типов. В пользовательском интерфейсе это преобразуется в раскрывающееся поле, которое позволяет пользователю выбрать тип, ИЛИ метку, которая просто отображает текстовое представление типа (в зависимости от того, какой экран это). Теперь, должен ли VO иметь свойство для идентификатора типа, текстовое представление типа или оба? Кто отвечает за перевод между ними и когда?

5) VO имеют поле для своего идентификатора базы данных. Я думал, что у ВО нет идентичности? Что с этим?

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

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

Ответы [ 3 ]

3 голосов
/ 04 октября 2008

1. Учитывая трансформацию DAO - VO; полезно ли это, зависит от того, как используется Hibernate. Если вся обработка веб-запросов выполняется в одном сеансе Hibernate, вам не нужно использовать отдельные VO.

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

Короче говоря, перед тем, как вы начнете расставаться с этими VO, внимательно изучите транзакции базы данных и границы сеансов.

3. Что касается использования VO в форме; если VO хорошо отображается на JSP, я бы сказал, почему нет? Меня либо впечатлило, что модель данных так близко соответствует процессу, который она поддерживает, и немного подозрительно, что база данных не была нормализована (что может создавать или не создавать проблемы в будущем).

Возвращаясь к 1. Если вы используете DAO с отложенной загрузкой и коллекциями, помните, что сеанс базы данных должен также включать фазу JSP, поскольку DAO будет считываться на этой фазе.

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

  2. Что вам нужно из запроса, так это идентификатор поля внешнего ключа. Поскольку это исходит от клиента, вам, вероятно, следует проверить в бизнес-логике, существует ли объект с таким идентификатором.

В зависимости от того, принимает ли VO идентификатор стороннего объекта или требует объекта, вам следует либо:

  • установить идентификатор или
  • получить посторонний объект в виде VO по идентификатору, используя сервисный уровень и положить его в свой VO, и сохранить его с помощью сервисного слоя

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

И если я правильно прочитал ваш вопрос, ваши VO обращаются к другим объектам в базе данных по id. В этом случае вы вводите идентификатор. Если вы получаете String от клиента, вы должны найти его на бизнес-уровне (используя сервисный уровень) и поместить идентификатор найденного объекта в VO. Или, если идентификатор не найден, верните достойное сообщение об ошибке.

В качестве заключительной записки; не трогай вещь DAO-VO, если ты не знаешь, что делаешь ДЕЙСТВИТЕЛЬНО ХОРОШО. Hibernate - это мощный и сложный инструмент, который обманчиво прост в использовании. Вы можете очень легко совершать ошибки, и их очень трудно найти. И клиенты, и начальство, похоже, не ценят появление ошибок в вещах, которые раньше работали.

Кстати; Мой консерватизм в DAO-VO связан с исправлением проблем, связанных с аналогичными проблемами в переходах EJB2 и Hibernate. Дьявол кроется в деталях, и изменение того, как вы справляетесь со слоем данных, является серьезным рефакторингом, даже если он выглядит как кусок пирога.

1 голос
/ 03 октября 2008

1) Нет необходимости в отдельном ВО и организациях: некоторые компании предоставляют такую ​​структуру для своего проекта. Это могло бы иметь смысл в другом проекте, и, следовательно, оно было поручено (я могу только догадываться)

2) Сервисный уровень: это естественное отделение от DAO и Action-уровня, верно?

3) Это не повредит, однако значение Объекты связаны, пока они правильно проверены перед отправкой в ​​DAO

4) Сервисный уровень должен отвечать за перевод между ними. Во время загрузки и экономии времени

5) если у них нет идентификаторов, как бы вы предотвратили дублирование?

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

0 голосов
/ 04 октября 2008

Чтобы ответить на вашу последнюю часть, используйте Spring MVC вместо Struts. Тогда вы можете просто использовать одни и те же доменные объекты на всех уровнях - классы, которые связываются с параметрами формы, также используются в Hibernate и содержат настоящую бизнес-логику.

Например, в приложении, которое я делал с помощью Spring MVC, у меня был класс-член. Логин, регистрация, смена пароля и форма редактирования профиля были привязаны к этому классу. Класс также имел отображение гибернации и большую часть бизнес-логики внутри (например, для социальной сети - метод «добавить друга»).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...