it-swarm.com.ru

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

Я знаю, что это, вероятно, извечный вопрос, но что лучше? Использование объекта модели предметной области во всех слоях вашего приложения и даже привязка значений непосредственно к ним в 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;

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

49
sma

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

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

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

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

33
srmark

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

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

8
Igor Zevaka

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

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

7
bennidi

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

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

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

2
Aquarelle

Сценарии, когда Domain Object проблематично отправлять:

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

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

2
Al1998

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

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

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

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

0
Ilan Y