DTO или объект модели домена в слое представления?

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

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

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

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

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

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

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

но, возможно, Вам не понадобится вся эта информация. Вам просто нужна фамилия учителя, количество учащихся, которые они учат в этом году и средний балл для всех студентов вместе взятых. Что бы вы сделали в таком случае? Извлеките полную информацию об учителе и отношениях с учащимися, а затем ваш код получит подсчет в списке учащихся, а затем вычислит общее число в среднем все значения внутри? Это похоже на waaaay больше усилий, чем просто создание DTO с "string lastName", "int numStudents" и " double combinedGpa;

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

8 ответов


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

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

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

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


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

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


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

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


сценарии, когда объект домена проблематичен для отправки:

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

Я не уверен, что это четкий ответ в этих cirumcstances


на мой взгляд, нет никаких проблем с использованием моделей объектов предметной области в каждом слое. Ты сказал, что тебе не нужна вся информация. Когда вы находитесь в JSPs, используйте только те данные, которые вам нужны. Никто не принуждает вас забирать все имущество. Вы также сказали, что вам нужно сделать вычисления, связанные со свойствами объекта, чтобы получить GPA, # студентов и т. д. У вас есть 3 варианта: создание синтетических свойств в объекте модели домена, которые возвращают правильные данные для вас, завернутый красиво и аккуратно; выполните вычисления в контроллере или сервисном слое и выставьте их через соответствующие геттеры; или обработайте все это внутри вашего JSP. В любом случае вам нужно получить/скомпилировать/обработать данные, поэтому зачем добавлять больше сложности с DTO.

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

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


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

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

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

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


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

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

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


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

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