То, как вы задаете вопрос (и предлагаете две альтернативы), заключается в том, что единственное беспокойство заключается в том, что driverId остается действительным на момент создания автомобиля.
Однако вы также должны быть обеспокоены тем, что драйвер, связанный с driverId, не удаляется до того, как автомобиль будет удален или передан другому водителю (и, возможно, также, что водитель не назначен другому автомобилю (это если домен ограничивает драйвер только быть связанным с одной машиной)).
Я предлагаю, чтобы вместо валидации вы выделяли (что включало бы валидацию присутствия). Затем вы будете запрещать удаление, пока оно еще выделено, таким образом, защищая от состояния устаревших данных во время построения, а также от другой долгосрочной проблемы. (Обратите внимание, что распределение как проверяет, так и отмечает выделение, и работает атомарно.)
Кстати, я согласен с @PriceJones, что связь между автомобилем и водителем, вероятно, является ответственностью, отдельной от автомобиля или водителя. Такая связь со временем будет только усложняться, потому что это звучит как проблема с расписанием (водители, машины, временные интервалы / окна, заменители и т. Д.). Даже если это больше похоже на проблему с регистрацией, может потребоваться историческая проблема. регистрации, а также текущие регистрации. Таким образом, он вполне может заслужить свою собственную БК.
Вы можете предоставить схему распределения (например, логическое или ссылочное число) в пределах BC совокупных объектов, которые выделяются, или в пределах отдельного BC, скажем, того, который отвечает за установление связи между автомобилем и водителем. Если вы делаете первое, вы можете разрешить (действительные) операции удаления, выданные автомобилю или водителю BC; если вы сделаете последнее, вам нужно будет предотвратить удаление из BC автомобиля и водителя и вместо этого отправить их через планировщик ассоциации автомобиля и водителя.
Вы также можете разделить некоторые обязанности по распределению между BC следующим образом. Каждое BC автомобиля и водителя предоставляет схему «распределения», которая проверяет и устанавливает выделенное логическое значение с этим BC; когда установлено их логическое распределение, BC предотвращает удаление соответствующих объектов. (И система настроена таким образом, что BC автомобиля и водителя разрешает только распределение и освобождение из BC BC планирования движения).
BC планирования автомобиля и водителя затем ведет календарь водителей, связанных с автомобилем, на некоторые периоды времени / продолжительности, сейчас и в будущем, и уведомляет другие BC о освобождении только о последнем использовании запланированного автомобиля или водителя.
Как более радикальное решение, вы можете рассматривать BC и Car & Driver как фабрики с историческими записями только для дополнения, оставляя право собственности на планировщик ассоциации Car / Driver. Автомобиль BC может генерировать новый автомобиль, в комплекте со всеми деталями автомобиля, а также его VIN. Право собственности на автомобиль обрабатывается планировщиком ассоциации автомобилей / водителей. Даже если связь между автомобилем и водителем удалена, а сам автомобиль уничтожен, записи об автомобиле все еще существуют в автомобиле BC по определению, и мы можем использовать автомобиль BC для поиска исторических данных; в то время как ассоциации / владения автомобиля / водителя (прошлые, настоящие и, возможно, запланированные на будущее) обрабатываются другим BC.
Driver.delete
не должно существовать Я никогда не видел домена, где агрегаты разрушаются. Держа AR вокруг, вы никогда не получите сирот.Это может помочь спросить: вы уверены, что автомобили построены с водителями? Я никогда не слышал об автомобиле, состоящем из водителя, в реальном мире. Причина, по которой этот вопрос важен, заключается в том, что он может указать вам направление на самостоятельное создание автомобилей и водителей, а затем создание какого-либо внешнего механизма, который назначает водителя на автомобиль. Автомобиль может существовать без справки водителя и при этом оставаться действующим автомобилем.
Если автомобиль должен иметь водителя в вашем контексте, то вы можете рассмотреть модель строителя. Этот шаблон будет отвечать за обеспечение того, что автомобили построены с существующими водителями. Фабрики будут обслуживать независимо проверенных автомобилей и водителей, но строитель будет гарантировать, что автомобиль имеет ссылку, в которой он нуждается, прежде чем он обслуживает автомобиль.
источник
Я думаю так. Выборка данного DriverId из БД возвращает пустой набор, если он не существует. Таким образом, проверка возвращаемого результата делает ненужным выяснение, существует ли он (и затем извлечение).
DriverId
и задается в конструкторе.Car
нужно толькоDriverId
, естьDriver.Id
добытчик. Нет сеттера.Car
заботится, если у него естьDriver
(или, по крайней мере, его ID). АDriver
заботится, если у него естьDriverId
. ВRepository
заботится о целостности данных и не мог заботиться меньше о водителе меньше автомобилей.DriverId
является бизнес-доменом, обрабатывается в соответствующих классах.... происходит, когда
Repository.DriverIdExists()
задает вопрос.Построить доменный объект. Если не
Driver
то , возможноDriverInfo
(как разDriverId
иName
, скажем) объект. УтвержденоDriverId
при строительстве. Он должен существовать и быть правильным типом, и все остальное. Тогда это проблема дизайна клиентского класса, как работать с несуществующим driver / driverId.Может быть,
Car
хорошо без водителя, пока вы не позвонитеCar.Drive()
. В этом случаеCar
объект, конечно, обеспечивает свое собственное состояние. Не могу ездить безDriver
- ну, пока не совсем.Конечно, есть,
Car.DriverId
если хотите. Но это должно выглядеть примерно так:Не это:
Теперь
Car
нужно разобраться со всеми вопросамиDriverId
обоснованности - нарушение принципа единой ответственности; и избыточный код, вероятно.источник