2012-06-26 3 views
3

Я новичок в принципах DDD и OO, извините за свои плохие знания.Объект домена расширяет объект передачи данных

У меня есть CustomerDTO и Клиент классы.

хранить все поля и свойства в DTO класса и использовать его в качестве базы класса для Клиента класса.

Основная цель использования DTO - передать его View. Я расширил его в . Класс не должен иметь дублирование свойств.

Правильно ли это сделать или есть лучшее решение OO?

Я читал об AutoMapper, но хотел бы знать, есть ли альтернативное решение.

Большое спасибо за любую помощь.

+1

Dto == структурный, Do == поведенческий. В какой вселенной они бы разделили базовый класс? –

+0

DO == поведение + структура == поведение + Dto. Так я и думал. – hgulyan

+1

DO = структурировано для ** транзакций **, DTO = структурировано для ** запроса ** данных для отображения в пользовательском интерфейсе. Их структуры и ** должны быть разными. Попытка объединить их вместе приведет к плохой ситуации. –

ответ

5

Я лично никогда не видел такого подхода. Причина, по которой вы используете DTO, - это разделение проблем между DAL и словом biz. Это позволяет бизнес-слою и DAL менять свои собственные шаги с минимальными побочными эффектами. Все, что вам нужно сделать, это изменить отображения между DTO и DO. Если вы наследуете свой DO от своего DTO, в чем смысл даже иметь DTO?

Быстрый ответ: не наследуйте свое ПО от вашего DTO. Это может быть легко сейчас, но это может стать кошмаром в будущем.

PS Не бойтесь Automapper. Его относительная простота использования.

+0

Благодарим вас за четкий ответ. Я был уверен, что я ошибаюсь, но не знал, как использовать классы DTO без дублирующих свойств. Разве нет решения, чтобы избежать дублирования? – hgulyan

+0

Дублирование в порядке, потому что у них две разные цели. Теперь они могут быть одинаковыми, но если их нужно изменить, проблем не будет. Automapper поможет с некоторой болью передачи данных. Как только вы это поймете, вы сможете отобразить 55 объектов в двух строках. –

+0

@ RyanBennett Описание DTO, как вы сделали, неверно: http://martinfowler.com/eaaCatalog/dataTransferObject.html – Rui

0

развернутый ответ:

Давайте попробуем проанализировать эту ситуацию, не слепо говоря, что ни один не делать такие вещи.

DTO - это структуры, которые содержат только данные и передают их между границами.

Модель домена - ключевое слово здесь «Модель» - это абстракция вашего домена, которая решает его проблемы. Из представления OO это простой класс, если вы разложите его на части, это будут чистые данные (DTO) и чистое поведение без гражданства (служба или доменная служба в терминах DDD).

Теперь давайте возьмем пример шаблона MVVM, особенно его часть VM. View Model - ключевое слово здесь снова «Модель» - это абстракция взгляда, которая решает ее проблемы. Есть много способов, которыми люди это реализуют, некоторые объекты Domain Domain, некоторые из них конвертируют, некоторые обертывают DTO. Дело в том, что View Model - это модель домена для представления, она почти такая же, как любая модель. Тогда почему люди ограничивают способ реализации Domain Model.

Теперь вернемся к модели DTO и доменов. Как я сказал выше, мы можем разбить объект домена на DTO и службу. Давайте рассмотрим, что мы рассматриваем объект Domain как поведенческую оболочку вокруг DTO (как, например, MVVM). Где это ведет нас:

  • Сначала мы прерываем инкапсуляции OO. Это плохо, потому что это предотвращает неправильное использование наших данных объекта.Кто-то может заставить данные объекта домена (DTO) напрямую манипулировать им и помещать нашу модель в недействительное состояние. Это огромно.
  • Мы можем легко перенести границы объекта, веб-сервисы, сериализацию, клонирование, мы можем отделить часть данных и предоставить ее нашему хранилищу данных или веб-сервису. Это очень важно для распределенных систем.

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

Теперь о повторном использовании DTO, Inheritance vs Composition. Кто-то сказал: предпочитайте композицию над наследованием, и я лично следую этому правилу. Но вам нужно проанализировать ваши конкретные ситуации. Правило говорит «предпочитают» не подчиняться.

Оригинал Asnwer:

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

Я видел такие вопросы, заданные много раз, и все ответы были: не делайте этого, потому что никто не делает таких вещей. Не бойтесь экспериментировать.

Райан Беннет написал в своем ответе:

Это может быть легко сейчас, но это может быть Мейнтаненс кошмар в будущем.

Ну, это правда, но что, если будущего не будет, или это небольшой проект, я бы придерживался правил YAGNI, TDD и Agile и выполнял минимальную работу, которая выполняет эту работу.

Код не то, что вы гравируете в камне и никогда не касаетесь, когда вам нужно, вы можете реорганизовать и ввести DTO, использовать auto-mapper или что-то еще.

+0

Приятно слышать, что это решение не так уж плохо: D Ну, это большой проект (не маленький по крайней мере), и рефакторинг будет очень тяжелым после того, как мы закончим. Кроме того, есть еще одна проблема, которую я боюсь. Мой объект домена не сможет расширять любой другой класс. С другой стороны мне не нравится факт дублирования свойств. – hgulyan

+0

Я использую подобный подход прямо сейчас в проекте среднего размера (10 разработчиков, 300-400 распределенных машин, участвующих в шине сообщений). Но я предпочитаю композицию над наследованием. Моя модель домена (объекты) содержит DTO и добавляет поведение (методы) над ними. –

+0

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

2

Плохая идея. Вот две причины (возможно, еще несколько):

  • Объекты домена специально структурированы для транзакций. Они не должны предоставлять публичный доступ ко всем объектам недвижимости. Они должны содержать только свойства, которые обеспечивают поведенческую цель. У DTO есть одна цель: предоставить данные потребителю (например, UI/Web Service/Message System). Например, клиент DTO может содержать свойства, которые предоставляют количество заказов, сделанных клиентом, и общую сумму денег, которую они потратили. Однако на стороне домена клиент агрегат, вероятно, не будет содержать никакой информации, поскольку эта информация о заказе хранится в отдельной совокупности заказов, специально предназначенной для транзакций заказа.
  • DTO - это немые POCO с только кучей геттеров & сеттеры. Это очень плохая практика, позволяющая вашим объектам домена иметь сеттеры для всех своих свойств. Операции должны быть атомарными и предоставляться методами, которые имеют явные имена, описывающие их намерения. Ответ на вопрос this объясняет этот момент.
+0

DTO - это не только пользовательский интерфейс, но и веб-службы и автобусы сообщений являются первичными «потребителями» DTO –

+0

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

+0

@AlexBurtsev это действительно правда, а просто семантика, а не моя точка. Моя точка зрения: DO's предназначены для одновременных транзакций с изменением состояния, причем данные инкапсулируются за атомными операциями. Они не должны просто быть DTO + некоторыми методами. –

0

Старый вопрос, и мне нравится несколько других ответов здесь, в частности, о разделении DAL с бизнес-уровня. ОДНАКО, я хотел бы упомянуть конкретную проблему, с которой вы можете столкнуться, когда классы DO наследуются от классов DTO.

В .NET языков, таких как C# и VB, вы не можете иметь истинное множественное наследование. Это класс не может распространять два базовых класса. Поэтому, если ваш класс DO уже расширяет базовый класс DTO, вы исключаете возможность наследования между классом DO и другим классом DO.

Игнорируя то, что таблицы выглядеть на самом деле сохраняются данные, или использовать вы TPH, TPT, or TPC, представьте, что вы есть DO классы для

Vehicle 
Car : Vehicle 
Boat : Vehicle 

Вы не можете иметь Car : CarDto, Vehicle. Если вы проектируете достаточно сложно, чтобы иметь какое-либо наследование между классами DO, то это довольно убедительный аргумент сам по себе.

Наконец, я хотел бы только добавить, что при выборе между наследованием по сравнению с композицией, вы думаете, с точки зрения «это» против «есть». Так что имеет смысл: «Автомобиль CarDto» или «Автомобиль - это автомобиль»? Последний ИМО.

 Смежные вопросы

  • Нет связанных вопросов^_^