2010-04-21 9 views
48

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

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

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

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

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

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

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

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

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

ответ

30

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

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

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

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

-4

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

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

+0

Да, я понимаю. Похоже, что иногда добавляет ненужную сложность. Если у меня есть объект, который говорит, представляет собой Учителя, и мне нужны только данные заголовка (имя, адрес), я должен отправить наполовину заполненный объект домена в интерфейс. Это своего рода вводящий в заблуждение и не кажется мне правильным. – sma

+4

@ smayers81 - почему вы только заполняете свои объекты домена на полпути? Это звучит как ненужная оптимизация (не если вы профилировали или иначе открыли проблему, конечно). Это звучит как корень вашей проблемы - обработка ваших доменных объектов, таких как DTO. Почему бы просто не подтолкнуть ваши полностью гидратированные объекты домена к интерфейсу? Если вы обнаружите, что у вас проблема с производительностью, у вас есть случай для DTO (или для обхода пользовательских объектов в целом и прямой работы с любой абстракцией набора записей, предоставляемой вашей инфраструктурой). –

+0

Потому что я всегда чувствовал, зачем отправлять все эти данные по проводам, если это не нужно. Я думаю, что это был весь толчок идее ленивого извлечения Hibernate (я мог ошибаться) – sma

7

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

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

+3

Я думал, что для сеанса требуется сериализация управление состоянием в кластерных средах? Даже объекты модели, которые мы имеем сейчас (Hibernate и пользовательские, отдельные), являются Serializable. – sma

+2

Я не думаю, что он имел в виду сериализацию, о которой вы говорите (a-la Serializable).Я думаю, он имел в виду сериализацию таких вещей, как XML, JSON, AMF (Flex), CSV и т. Д. – Aquarelle

2

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

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

Я не уверен, что это однозначный ответ в этих cirumcstances

7

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

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

1

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

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

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

-1

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

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

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

0

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

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

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

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