#c_sharp #ddd
Имеется сущность "Клиент" (Customer). Клиент может иметь 1 номер мобильного телефона и 1 адрес электронной почты. Телефонный номер, как и адрес электронный могут быть в двух состояниях - "Не подтвержден" и "Подтвержден". Забегая вперед, скажу, что все эти 4 параметра должны храниться в одной таблице Customers, дабы избежать лишних JOIN'ов. Мой главный вопрос: как смоделировать доменную модель? Атрибуты PhoneNumber и IsPhoneNumberConfirmed (как и Email и IsEmailConfirmed) выглядят так, как будто выражают нечто целое. Можно было бы определить ValueObject Communication с двумя параметрами Value и IsConfirmed. Тогда, класс Customer мог выглядеть бы так: public class Customer { public Communication Phone { get; private set; } public Communication Email { get; private set; } } Но как быть с тем фактом, что IsConfirmed это по сути - состояние объекта (что, если я не ошибаюсь, противоречит концепции ValueObject)? Наверное, было бы удобно с точки зрения API определить метод Communication.Confirm(), который изменит состояние IsConfirmed на true. Что, опять же противоречит концепции ValueObject (VO должен быть неизменяемым после создания). Возможно это Entity? Тогда эти объекты должны хранится в отдельных таблицах в БД? Это противоречит тому, что описал в начале ("...все эти 4 параметра должны храниться в одной таблице Customers"). Может быть, я сделал неверное предположение, что атрибуты PhoneNumber и IsPhoneNumberConfirmed должны является частью одного объекта? Может быть, метод подтверждения средства связи должен находится в классе клиента: Customer.ConfirmMobilePhone()? Ведь, это клиент подтверждает телефон, а не телефон подтверждает сам себя.
Ответы
Ответ 1
На самом деле, спроектировать можно по разному. Если подойти к вопросу канонически, то у вас телефон это Entity потому что он имеет идентичность и жизненный цикл. При этом, совсем не обязательно телефон должен быть корнем агрегации(хотя может, вдруг вы хотите отслеживать у телефонов смену владельца). Если сущность не является корнем агрегации, то она обязательно относится к какому то агрегату, в вашем случае к Customer. При этом, совершенно не важно где эта сущность хранится, в отдельной таблице или в поле у клиента. DDD вообще не накладывает таких ограничений. Вспомните по не реляционные БД, где все сущности агрегата вообще хранятся одним блобом. С другой стороны можно смотреть на телефон как на характеристику клиента, который меняет одну свою характеристику (имею неподтвержденный телефон ХХХ-ХХХ) на другую характеристику (имею подтвержденный телефон ХХХ-ХХХ) и тогда уже у вашего телефона нет ни идентичности ни жизненного цикла, а это уже честный Value Object. В вашем случае разница вообще не существенна, выберите любой вариант из двух и храните где вам удобнее. Еще два момента по вашему тексту: Не фокусируйтесь на том что Value object не изменяемый, лучше что это только характеристика Entity как цвет, размер или максимальная скорость. То что телефон подтверждает сам себя в ООП вообще норма.
Комментариев нет:
Отправить комментарий