DDD и источник событий: истечение срока в виде спецификации или команды?

Фон

Я пытаюсь применить 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.
  • После этого мы считаем, что AuctionEXPIRED, а 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. Кроме того, если я управляю истечением срока с помощью запланированных задач, мне кажется, что моя модель предметной области предполагает простоту чтения, которая сильно связана с требованиями приложения.

Если вы столкнулись с подобными проблемами, пожалуйста, помогите мне с вашим опытом.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
342
2

Ответы 2

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

Причины, по которым вы все же можете захотеть добавить события 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

Я бы добавил в качестве пояснения, что он находится в модель предметной области; Обычно нет необходимости выводить часы за пределы приложения.

Одна из ключевых идей при выборе подхода - является ли модель предметной области полномочием для принятия решения о завершении аукциона или просто отслеживает решения, принятые где-то еще?

Ваш первый подход связан с идеей, что модель является авторитетом; приложение сообщает модели, который час, модель решает, завершать аукцион или нет.

Ваш второй подход согласуется с идеей, что модель является просто бухгалтерской - «конечный аукцион», исходящий из-за пределов модели это.

Любой подход может быть «правильным», в зависимости от того, что вы создаете.

Учитывая остальную часть вашего описания, я думаю, что вы пытаетесь построить решение первого типа, поэтому вам следует подумать о том, чтобы сообщить модели предметной области, который час, и позволить модели решить, означает ли это аукцион. окончено.

Предупреждение: получение права сантехника может быть проблемой: как приложение узнает, что аукционам который нужно время? Сохраняется ли расписание при перезапуске приложения? и так далее.

Другие вопросы по теме