Объекты значения в CQRS - где использовать - PullRequest
35 голосов
/ 02 февраля 2011

Скажем, у нас есть архитектура, основанная на CQRS, с такими компонентами, как команды, модель домена, события домена, DTO модели чтения модели.
Конечно, мы можем использовать объекты значений в нашей модели домена.У меня вопрос, должны ли они также использоваться в:

  1. Команды
  2. События
  3. DTO

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

Моя мотивация:

Команды.
Допустим, пользователь отправляет форму, которая содержит поля адреса.У нас есть Address Value Object, чтобы представить эту концепцию.При построении команды в клиенте мы должны все равно проверять вводимые пользователем данные, и, когда они правильно сформированы, мы можем сразу создать объект Address и инициализировать Command с ним.Я не вижу необходимости делегировать создание объекта Address обработчику команд.

События домена.
Модель домена уже работает в терминах объектов-значений, поэтому, публикуя события с VO вместо преобразования их в примитивные типы, мы можем избежать некоторого кода отображения.Я почти уверен, что в этом случае можно использовать VO.

DTO.
Если наши DTO на стороне запроса могут содержать объекты-значения, это обеспечивает большую гибкость.Например, если у нас есть объект Money, мы можем выбрать, отображать ли его в евро или долларах США, не нужно менять модель чтения.

Ответы [ 4 ]

25 голосов
/ 07 февраля 2011

Хорошо, я передумал. В последнее время я пытался разобраться с ВО, и после просмотра этого http://www.infoq.com/presentations/Value-Objects-Dan-Bergh-Johnsson он прояснил для меня пару вещей.

Команды и Событие являются сообщениями (а не объектами, объекты - это данные + поведение), в некоторых отношениях во многом подобно DTO, они передают данные о событии и сами по себе не содержат никакого поведения.

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

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

Перефразируя Орена (хотя он имел в виду nHibernate и WCF) "Не пересылайте свой домен по проводам". http://ayende.com/Blog/archive/2009/05/14/the-stripper-pattern.aspx

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

Оригинальный текст (для потомков):

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

При этом объект значения представляет такие понятия, как, например, цвет. У вас нет зеленого , у вас зеленый или нет. Кажется, нет ничего плохого в том, что команда, сообщающая вам, что вы зеленеете, передавая это.

Чтение главы из DDD, посвященной шаблону Aggregate Root, довольно хорошо объясняет сущности и объекты-значения и стоит прочитать несколько раз.

4 голосов
/ 02 февраля 2011

Я говорю, что это плохая идея.

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

Этого следует избегать.

Используйте DTO и / или примитивы.Отобразите их (AutoMapper заключает сделку в одну строку).

3 голосов
/ 17 февраля 2011

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

0 голосов
/ 25 сентября 2014

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

Я не считаю правильным помещать объекты значения в DTO с точки зрения архитектуры.Объекты значений находятся внутри модели предметной области, а упомянутые вами DTO определяют интерфейс модели.Обычно мы создаем интерфейс, чтобы отделить внешний мир от чего-то внутри.Таким образом, в текущем случае мы добавили DTO для отделения внешнего мира от объектов-значений (и других вещей, связанных с моделью).После этого добавление объектов-значений в интерфейс сводит с ума.

Таким образом, вы еще не встретили это решение, потому что это анти-шаблон.

...