DTO или объект модели предметной области на уровне представления? - PullRequest
49 голосов
/ 21 апреля 2010

Я знаю, что это, вероятно, давний вопрос, но какая практика лучше? Использование объекта модели предметной области на всех уровнях вашего приложения и даже привязка значений непосредственно к ним в JSP (я использую JSF). Или преобразуйте объект модели домена в DTO на уровне DAO или Service и отправьте облегченный DTO на уровень представления.

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

Я должен отметить, что мое приложение использует объекты модели Hibernate И использует свои собственные объекты модели, созданные пользователем (то есть не привязанные к какому-либо сеансу БД, всегда отключенные). Является ли какой-либо из приведенных выше сценариев более полезным для строгого шаблона объекта модели? Использование Hibernate было огромной PITA в отношении таких вещей, как исключения Lazy Initialization.

Я редактирую этот вопрос в надежде продолжить обсуждение (не уверен, правильно ли я делаю):

Проблема, с которой я сталкиваюсь с модельными объектами, заключается в том, что они вообще не являются гибкими. Комментарий ниже говорит о том, что приложение должно быть спроектировано так, чтобы объекты модели могли использоваться на всех уровнях. Зачем? Если пользователь хочет получить часть нелепой функциональности, я должен сказать им: «Ну, это не будет работать с объектами модели»?

Простые и понятные моменты, когда объекты модели не работают. Вы можете иметь:

public class Teacher {
    List<Student> students;
    [tons of other Teacher-related fields]
}
public class Student {
    double gpa;
   [tons of other Student-related fields]
}

но, возможно, вам не нужна вся эта информация. Вам просто нужны фамилия учителя, количество учеников, которых они обучают в этом году, и средний средний балл для всех учеников вместе взятых. Что бы вы сделали в этом случае? Получите полную информацию об учителе и взаимоотношениях со студентами, а затем ваш код получит счет в Списке студентов, а затем вычислит общее среднее значение всех gpas внутри? Это похоже на большие усилия, чем просто создание DTO с «String lastName», «int numStudents» и «двойной комбинированный Gpa;

»

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

Ответы [ 8 ]

33 голосов
/ 27 сентября 2011

Это действительно зависит от сложности вашего приложения. Смешивание доменных объектов в слое представления имеет два возможных значения:

  1. Вы будете склонны изменить свой объект домена, чтобы разместить вещи, которые вам нужны в слое представления
  2. Ваш слой View будет содержать дополнительную сложность, вызванную несоответствием между тем, что предлагают ваши доменные объекты, и тем, что действительно нужно вашему представлению. Возможно, вам не удастся обойти эту сложность, но она, вероятно, не относится к слою View.

Если ваши доменные объекты просты и у вас мало просмотров, пропустить DTO может быть самой простой вещью.

С другой стороны, если ваша модель предметной области, вероятно, будет развиваться и становиться сложной, и если ваши представления, вероятно, будут многочисленными и разнообразными, хорошей идеей может быть представление конкретных объектов. В мире MVC использование ViewModels является обычным делом и имеет для меня большой смысл.

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

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

Я считаю DTO полезными только там, где объекты должны быть сериализованы. Если нет передачи по проводам или в несовместимую архитектуру, я бы их не использовал. Шаблон DTO полезен для предотвращения сериализации вне доменного объекта. Учитывая, что взаимодействие между пользовательским интерфейсом и доменом не требует сериализации, сделайте его простым и используйте реальные объекты.

7 голосов
/ 20 декабря 2011

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

Я приобрел хороший опыт работы с моделью представления, которая охватывает только доменные объекты и делегирует им большинство операций. Это разделяет представление и слой домена, позволяет гибко составлять объекты домена и по-прежнему не требует много усилий для реализации. поскольку IDE поддерживают шаблон делегирования.

2 голосов
/ 10 апреля 2013

На мой взгляд, нет проблем с использованием объектов модели предметной области в каждом слое. Вы сказали, что вам не нужна вся информация. Когда вы находитесь в JSP, используйте только те данные, которые вам нужны. Никто не заставляет вас забирать каждую собственность. Вы также сказали, что вам нужно делать расчеты, связанные со свойствами объекта, чтобы получить средний балл, количество учеников и т. Д. У вас есть 3 варианта: создать синтетические свойства в вашем объекте модели домена, которые возвращают нужные вам данные, завернутые приятно и аккуратный; выполнять вычисления на уровне контроллера или службы и выставлять их через соответствующие методы получения; или обрабатывать все это внутри вашего JSP. Вам нужно ПОЛУЧИТЬ / скомпилировать / обработать данные В ЛЮБОМ СЛУЧАЕ, так зачем добавлять сложность с помощью DTO.

Кроме того, с каждым DTO вы создаете.) Дополнительный класс, который вы теперь должны поддерживать, и b.) В дополнительном методе LEAST 1 где-то в каком-то классе, который создает и заполняет DTO (DAO, фабричный метод, так далее.). Больше обслуживания = несчастный разработчик через 6 месяцев.

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

2 голосов
/ 10 июля 2010

Сценарии, когда Доменный объект проблематично отправить:

  1. вам может потребоваться агрегированная информация или другие типы «вычисляемых полей», отправленные на уровень пользовательского интерфейса (например, Flex / GWT), и вы не хотите путать объект домена
  2. вы можете столкнуться с необходимостью сериализации графа циклических объектов (в вашем примере, если у ученика было отношение List), некоторые протоколы имеют проблемы с этим
  3. Hibernate LazyInitializationException при работе с сериализаторами фреймворка (blazeDS для сериализатора flex / GWT)

Я не уверен, что это ясный ответ при этих обстоятельствах

0 голосов
/ 23 марта 2015

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

Домен должен быть инкапсулирован и защищен от изменения кем-то, кто не имеет отношения к работоспособности домена.

Утечка поведения - не самая лучшая привычка.

Если это небольшой проект, постройте его с правильными принципами. Таким образом, мы всегда помним, почему мы делаем то, что делаем, а не просто как.

0 голосов
/ 18 августа 2013

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

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

И, наконец, я лично считаю, что доменные объекты должны быть переданы в само представление. Представьте себе, на что тогда похожа интеграция калитки. Но возьмем, например, Spring MVC - домен останется на уровне приложения, вероятно ...

0 голосов
/ 21 апреля 2010

В настоящее время DTO широко считается анти-паттерном, и обычно совет состоит в том, чтобы «избегать их любой ценой».

Одним из основных преимуществ инфраструктуры ORM, такой как Hibernate, является то, что вы можете использовать доменные объекты на всех уровнях и в действительности не нуждаетесь в DTO. Предостережение, конечно, заключается в том, что вы должны посвятить некоторое время ДУМАЮ об этих отношениях: когда использовать ленивую выборку, когда использовать нетерпеливый и т. Д.

...