Фон
Я пытаюсь применить ddd и источник событий к части моего проекта.
Это приложение для аукциона.
Customer
регистрирует Item
, а Auction
- это STARTED
, когда администратор approves
регистрирует Item
.Auction
имеет duration
, который позволяет Bidder
преобразовывать Bid
в duration
.Auction
считается ENDED
, после этого duration
и Bidder
не могут участвовать в торгах.Auction
также является ENDED
, когда встречается maximum bids limit
, даже если duration
не прошел.Customer
может select
, один Bid
внутри duration
и 5 days after the duration ends
.Auction
EXPIRED
, а Customer
не может select
как Bid
.Требования к кандидатам:
Bidder
должен иметь возможность запрашивать аукционы с назначением ставок.ended
и expired
только один раз.Подводя итог, я определил свои классические доменные модели DDD:
Сущности: Auction
, Bid
, Customer
, Administrator
, Bidder
Объекты значений: AuctionStatus
(STARTED
, ENDED
, EXPIRED
, SELECTED
)
Совокупные корни: Auction
, Customer
, Bidder
, Administrator
Проблема
Проблема в том, что я не уверен, что мне следует
A) определить спецификацию, такую как AuctionEndedSpecification
, и использовать ее для запроса и оценки состояния и действий ограничений.
или
Б) рассматривать EndAuction
как команду и помещать простой атрибут status
в Auction
сложная часть A: чтобы определить, истек ли срок аукциона или закончился, мне нужно текущее время, и это усложняет реализацию кода. И я думаю, что будет сложнее реализовать запрос.
сложная часть B: аукцион завершается по нескольким причинам (по истечении срока действия, при достижении максимального предела ставок). Я узнал, что не следует позволять одному событию запускать другое. Но в этом случае событие BidAdded
может вызвать событие AuctionEnded
. Кроме того, если я управляю истечением срока с помощью запланированных задач, мне кажется, что моя модель предметной области предполагает простоту чтения, которая сильно связана с требованиями приложения.
Если вы столкнулись с подобными проблемами, пожалуйста, помогите мне с вашим опытом.
Похоже, что состояние агрегата вашего аукциона можно рассчитать по событиям без каких-либо дополнительных событий. И на стороне записи, и на стороне чтения.
Причины, по которым вы все же можете захотеть добавить события AuctionEnded:
правила окончания аукциона, вероятно, изменятся в будущем, и тогда ваша логика расчета может стать очень сложной.
у вас есть внешняя служба, которая не хочет самостоятельно рассчитывать конечное состояние аукциона.
есть общий совет, что поток событий вашего агрегата должен быть доступен для чтения эксперту в предметной области. Думаю, мне бы хотелось увидеть в таком потоке отметку "AuctionEnded".
Если вы решите производить события AuctionEnded, вам понадобится Saga / ProcessManager, чтобы в нужный момент выдать команду «EndAuction».
To judge whether an auction is expired or ended, I need the current time and this makes the code harder to implement.
Обращаю ваше внимание на написание Джон Кармак
If you don't consider time an input value, think about it until you do - it is an important concept
Я бы добавил в качестве пояснения, что он находится в модель предметной области; Обычно нет необходимости выводить часы за пределы приложения.
Одна из ключевых идей при выборе подхода - является ли модель предметной области полномочием для принятия решения о завершении аукциона или просто отслеживает решения, принятые где-то еще?
Ваш первый подход связан с идеей, что модель является авторитетом; приложение сообщает модели, который час, модель решает, завершать аукцион или нет.
Ваш второй подход согласуется с идеей, что модель является просто бухгалтерской - «конечный аукцион», исходящий из-за пределов модели это.
Любой подход может быть «правильным», в зависимости от того, что вы создаете.
Учитывая остальную часть вашего описания, я думаю, что вы пытаетесь построить решение первого типа, поэтому вам следует подумать о том, чтобы сообщить модели предметной области, который час, и позволить модели решить, означает ли это аукцион. окончено.
Предупреждение: получение права сантехника может быть проблемой: как приложение узнает, что аукционам который нужно время? Сохраняется ли расписание при перезапуске приложения? и так далее.