Объекты Value в CQRS - где использовать

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

  • Команды
  • События
  • DTOS

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

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

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

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

DTOs.
Если наши DTO на стороне запроса могут содержать объекты Value, это обеспечивает некоторую гибкость. Например, если у нас есть объект Money, мы можем выбрать, показывать ли его в EUR или USD, не нужно изменять Read Model.

Ответ 1

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

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

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

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

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

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

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

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

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

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

Ответ 2

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

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

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

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

Используйте DTO и/или примитивы. Сопоставьте их (AutoMapper делает это сделкой с 1 строкой).

Ответ 3

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

Ответ 4

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

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

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