В проекте Ecommerce у нас есть основное разделение между слоем приложений и слоем доменов.
Мы стремимся к тому, чтобы домены были многоразовыми.
Приложения специфичны и не предназначены для многократного использования, по крайней мере, это не главная цель.
Я хотел бы поделиться своими текущими мыслями о том, что, по моему мнению, может помочь нам достичь хорошей модульности и возможности повторного использования.
Что делает домен?
- команды как единственный входной слой
- события как единственный выходной слой
- агрегаты как внутренний механизм, который поддерживает переходы состояний
- они могут быть объектами или функциями
В теории это все.
На практике иногда требуется нечто большее. Иногда у вас будет модель чтения, которая существует только для того, чтобы из нее можно было читать в данном BC (bounded context). Например, Pricing BC может потребоваться содержать свой собственный внутренний Pricing Catalog, из которого будут считываться цены.
Учитывая вышесказанное, мы хотим сохранить команды и события настолько гранулированными, насколько это возможно. Кроме того, мы хотим обеспечить возможность повторного использования.
Некоторые приложения могут захотеть иметь более красивые/большие команды или события. Это замечательно.
Они должны использовать паттерн EventSummaryBuilder, чтобы отталкиваться от мелких событий и создавать более крупные события.
Аналогично с командами, они могут захотеть создать большие команды — это замечательно, давайте просто покажем, как эти большие команды накладываются на существующие маленькие команды.
Эти конструкторы, по крайней мере, таково мое нынешнее мнение, не являются частью BC. Они являются частью прикладного слоя, потому что они настраиваются для приложения. В некотором смысле они являются фасадом, который может/должен обслуживаться приложением, как потребителем доменного кода.
Мы можем предоставить их как нечто многократно используемое, но это уже другие «блоки».
Сами по себе BC полезны, но они не создают особенность.
Функция — это набор строительных блоков, которые вместе образуют функциональную и рабочую единицу на уровне приложения в сочетании с доменом/БК.
Давайте рассмотрим выставление счетов.
Есть Invoicing BC со своими событиями и командами.
Есть менеджер процессов, который создает состояние Invoicing, реагируя на некоторые события Pricing. Это прикладной уровень.
Очевидно, что есть способ отображения счета для клиента.
Это модель чтения.
Есть также способ отображения счета для администратора, обычно отличающийся от счета для клиентов. Это еще одна модель чтения.
Эти модели чтения имеют свои собственные хранилища — они должны владеть ими. Миграции должны принадлежать моделям чтения.
Рендереры html/json также могут принадлежать моделям чтения.
Здесь тоже есть серая зона.
Насколько полезными могут быть БК без сопутствующих БК?
Можем ли мы представить, что БК Invoicing будет прекрасно работать без текущего Pricing?
Я думаю, это должно быть возможно.
Один из гипотетических сценариев — это создание типичного приложения для выставления счетов, без какого-либо окружения электронной коммерции.
Это общее представление о том, как все может работать.
Все может измениться, когда у нас будет больше приложений и больше возможностей для повторного использования, что покажет, какие части этого видения хрупки.
Мысли?