У меня есть совокупный корень под названием Пользователь.
Вот пример того, как это моделируется:
User: {
id: string
username: string,
email: string,
auth: LocalAuth {
password: string
}
}
В моем приложении у меня есть маршрут API -
ПОЧТА/users/id/password
- позволяет пользователям изменять свой пароль.
Чтобы изменить свой пароль, мы должны убедиться, что пользователи вводят свой старый пароль. Модель запроса должна выглядеть так:
{
oldPassword: string
newPassword: string
newPasswordRepeating: string // in case of user errors
}
Контроллер, обрабатывающий этот запрос, должен сделать следующее:
Чтобы справиться с такой бизнес-логикой, я мог бы создать модель ВО с именем PasswordUpdate (idk ..). Этот ВО может инкапсулировать логику проверки в свою собственную модель.
Точно ли такая реализация следует правилам DDD?
Потому что в моем случае этот VO никогда не содержится в Aggregate Root и не сохраняется. Цель состоит только в том, чтобы смоделировать обновление пароля с помощью модели предметной области.
Does this kind of implementation faithfully follows the DDD rules?
Очень короткий ответ: вперед.
Краткий ответ: полиция DDD в любом случае не будет преследовать вас, так что не думайте слишком долго.
Широкий ответ: я считаю, что описание объектов-ценностей Эвансом является чем-то вроде путаницы, загрязненной тем фактом, что он опирался на опыт работы с Java.
Но если вы посмотрите очень внимательно, то увидите, что Эванс предлагает создать предметно-ориентированный язык, который вы можете использовать для описания поведения модели. Объекты значений делают несколько вещей: они предоставляют вам типы, специфичные для предметной области (чтобы система типов могла помочь, насколько это возможно, в ограничении частоты определенных видов ошибок), они предоставляют вам семантику, специфичную для предметной области (а не настаивая на том, что все поведения домена описываются с помощью операций с примитивами, не зависящими от домена), и они обеспечивают уровень изоляции между поведением домена и представлениями состояния домена в памяти.
Значение этого не ограничивается «моделью предметной области»; вы можете свободно применять эту абстракцию везде, где это имеет смысл.
НО ... в описываемом вами случае есть особая ловушка, о которой вам следует знать.
Модель предметной области - это то, что вы должны агрессивно изменять для удовлетворения потребностей бизнеса, что, конечно же, может включать в себя изменение реализации объектов значений.
Однако Сообщения следует изменить консервативно. Сообщения являются частью API. Если мы хотим иметь возможность выпускать совместимые клиенты и серверы, используя разные каденции для каждого, то нам нужно, чтобы интерфейс между ними был стабильным. Сообщение не должно содержать правила домена (они принадлежат модели), это просто представление состояния.
«Проверка» обычно происходит, когда мы берем сообщение (часть API) и переводим его в значения, понятные модели.
Спасибо за это подробное объяснение :) Тогда лучший способ - поместить PasswordUpdate вне уровня домена, но, возможно, создать модели запросов или что-то в этом роде.
Не говоря уже о том, что есть часть операции, которая обязательно должна быть нет в IMO домена - часть newPassword == newPasswordRepeating
. Это UI или прикладные вещи.
Это пользователь, желающий изменить свой пароль во время входа в систему, или пользователь, сбрасывающий свой пароль, не входя в систему?
Полиция DDD вполне реальна, и они придут за вами.
Имейте в виду, что идентификация / аутентификация / авторизация почти никогда относятся к DDD / бизнес-уровню. Это инфраструктура и, следовательно, находится за пределами вашего домена и сильно зависит от вашей инфраструктуры (т. Е. Используемой инфраструктуры авторизации / идентификации) и внесет изменения в вашу инфраструктуру идентификации. Это не должно повлиять на ваш домен. И поэтому не рассматривайте "User" как объект домена. Просто относитесь к нему как к объекту / модели вашей инфраструктуры. Просто используйте идентификатор (guid, id и т. д.), Чтобы связать его с объектом в вашем домене (например, «Человек»).