DDD — Как отделить ограниченный контекст и поделиться событиями?

На самом деле я читаю книгу под названием «DDD в PHP», чтобы помочь мне понять дизайн, управляемый доменом. Пока все хорошо, но я изо всех сил пытаюсь понять, как реализовать одну конкретную тему, не связывая ограниченные контексты: доменные события

Допустим, у меня есть БЦ:

  • платежи: Обрабатывает создание счетов, отправку их клиентам и т. Д.
  • заказы: Обрабатывает создание заказов, их состояние и т. Д.

Когда Order помещен, OrderCreated Событие отправлено.
Payments BC ловит это событие с подписчиком и создает счет.

Проблема в том, если я хочу идеально разделить оба БК, где OrderPlaced Событие живое, так как оно используется обоими БК? Должен ли он жить за пределами обоих БЦ? В них обоих? Что если я захочу развернуть модуль Invoices как отдельный, не имея доступа к модулю Orders и его определению события OrderPlaced, это вызовет некоторые фатальные ошибки?

Заранее спасибо за ответы!

2

Решение

Проблема в том, что если я хочу идеально разделить оба BC, где должно жить событие OrderPlaced, поскольку оно используется обоими BC? Должен ли он жить за пределами обоих БЦ? В них обоих?

Я бы сохранил событие в контексте, которому оно принадлежит, то есть в контексте заказов. Как вы собираетесь разделять контексты? это физическое / сетевое разделение границ или просто концептуальное?

Что если я захочу развернуть модуль Invoices как отдельный, не имея доступа к модулю Orders и его определению события OrderPlaced, это вызовет некоторые фатальные ошибки?

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

В общем, есть несколько способов решения этой проблемы:

  1. Поделитесь общим определением. В C # (не уверен, что эквивалент будет в PHP) в прошлом у меня была отдельная библиотека классов в BC для событий, которые могут понадобиться другому BC (например, MyContext.Contracts dll), на которые затем может ссылаться другие до н. Они были опубликованы в виде внутренних лент новостей (менеджер пакетов), чтобы другие контексты могли постоянно обновляться.
  2. Слабая сериализация на конце подписки. Если вы подписываетесь на поток событий, вы можете иметь дело с необработанным представлением, в котором оно хранится (то есть в JSON), вместо того, чтобы некоторая библиотека автоматически десериализовала его в объект. Если вы пойдете по этому маршруту, я бы предложил некоторые «контрактные испытания» в издательской части, которая имитирует действия подписчика. Это защитит вас от разрыва ваших контрактов с внешним миром.
2

Другие решения

Хотя ответ принят, я бы хотел добавить свое мнение 🙂

Они объединяют ваши текущие BC, подписываясь непосредственно на опубликованные сообщения: Payments подписывается на OrderCreated, Этот стиль взаимодействия называется хореография. Это не обязательно плохо, но вы должны взвесить все за и против. Например, когда вам нужно добавить шаг между ними, вы можете иметь Address До н.э. подписаться на OrderCreated так что он может проверить адрес доставки. Теперь Payments БК должен подписаться на AdressValidated событие. Но опять же, это событие публикуется совсем немного, так как мы также используем его при регистрации клиентов. ммм …

Другой вариант заключается в использовании оркестровка где вы явно сохраняете состояние рассматриваемого процесса. Вы можете иметь OrderProcess и CustomerOnboardingProcess, После этого ваши текущие BC могут обрабатывать только сообщения внутри своих собственных BC. Другая процесс Затем BC координирует сообщения и отслеживает состояние.

Две другие проблемы, с которыми можно столкнуться в хореографии:

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

Я надеюсь, что в этом есть смысл.

1

Вопрос в том, Payments BC должен создать счет, потому что, как следует из названия, это должно быть payments и не orders или же invoices,

Может быть, что-то вроде этого:

Orders -> 'order created' -> Payments -> 'payment done' -> Orders -> 'invoice created'
0
По вопросам рекламы [email protected]