Spring MVC: должен ли сервисный уровень возвращать операции, специфичные для DTO? - PullRequest
7 голосов
/ 14 апреля 2010

В моем приложении Spring MVC я использую DTO на уровне представления для инкапсуляции модели предметной области на уровне обслуживания. DTO используются в качестве подпружиненных опорных объектов.

следовательно, мои сервисы выглядят примерно так:

userService.storeUser(NewUserRequestDTO req);

Сервисный уровень переведет DTO -> Domain object и выполнит остальную работу.

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

EditUserRequestDTO userService.loadUserForEdit(int id);

DisplayUserDTO userService.loadUserForDisplay(int id);

но что-то не так с этим подходом. Возможно, служба не должна возвращать такие вещи, как EditUserRequestDTO, а контроллер должен отвечать за сборку requestDTO из выделенного объекта формы и наоборот.

Причина, по которой есть отдельные DTO, заключается в том, что DisplayUserDTO строго типизирован для использования только для чтения, а также есть много свойств пользователя, которые являются сущностями из таблицы поиска в БД (например, город и штат), поэтому DisplayUserDTO будет иметь строку описание свойств, в то время как EditUserRequestDTO будет иметь идентификаторы, которые будут поддерживать выпадающие списки выбора в формах.

Что вы думаете?

спасибо

Ответы [ 2 ]

2 голосов
/ 24 августа 2016

Вы должны использовать DTO и никогда ORM в слое MVC! По этому вопросу уже задан ряд действительно хороших вопросов, таких как: Почему я должен изолировать свои доменные сущности от уровня представления?

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

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

Мне нравятся урезанные экранные объекты. Это более эффективно, чем создание целого доменного объекта только для отображения нескольких его полей. Я использовал похожий шаблон с одним отличием. Вместо использования редактируемой версии DTO, я просто использовал объект домена в представлении. Это значительно уменьшило работу копирования данных между объектами. Я не решил, хочу ли я сделать это сейчас, так как я использую аннотации для JPA и Bean Validation Framework и смешиваю аннотации, выглядит грязно. Но я не люблю использовать DTO с единственной целью - не допускать доменных объектов в слой MVC. Кажется, что много работы для небольшой пользы. Кроме того, было бы полезно прочитать мнение Фаулера о анемичных объектах . Возможно, это не совсем так, но стоит подумать.


1-е редактирование: ответ на комментарий ниже.

Да, мне нравится использовать реальные доменные объекты для всех страниц, которые одновременно работают с одним объектом: редактировать, просматривать, создавать и т. Д.

Вы сказали, что берете существующий объект и копируете нужные поля в DTO, а затем передаете DTO как часть модели в ваш движок шаблонов для страницы просмотра (или наоборот для создания). Что это покупает тебя? Ссылка на DTO весит не меньше, чем ссылка на полный объект домена, и у вас есть все дополнительные атрибуты копирования. Нет правила, согласно которому ваш шаблонизатор должен использовать каждый метод вашего объекта.

Я бы использовал небольшой частичный предметный объект, если бы он улучшал эффективность (без построения графиков отношений), особенно для результатов поиска. Но если объект уже существует, не беспокойтесь о том, насколько он велик или сложен, когда вы вставляете его в модель для отображения страницы. Это не перемещает объект в памяти. Это не вызывает нагрузку на двигатель. Он просто получает доступ к нужным методам и игнорирует остальные.


2-е редактирование: Хорошая точка зрения. Существуют ситуации, когда вам нужен ограниченный набор свойств, доступных для представления (т. Е. Разные внешние и внутренние разработчики). Я должен прочитать более внимательно, прежде чем ответить. Если бы я собирался делать то, что вы хотите, я бы, вероятно, поместил отдельные методы для User (или любого другого класса) в форме forEdit () и forDisplay (). Таким образом, вы можете просто вывести Пользователя из сервисного уровня и попросить Пользователя предоставить вам ограниченные копии его использования. Я думаю, может быть, это то, чего я достиг с комментарием анемичных объектов.

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