Макет модуля Maven для проектов DDD - PullRequest
5 голосов
/ 21 марта 2011

Как вы размещаете свои модули Maven при выполнении проектов DDD? Вы вписываете все слои (презентация, приложение, домен, инфраструктура) в один модуль или вы создаете многомодульный макет с отдельным модулем для каждого слоя? Или что-то еще целиком?

Я заметил, что Образец приложения DDD , разработанный компаниями Domain Language и Citerus, использует один модуль Maven, каждый слой которого находится в отдельном Java-пакете внутри этого модуля. Это установленный передовой опыт, или я должен рассмотреть более детальную компоновку модуля?

1 Ответ

9 голосов
/ 24 марта 2011

Как правило, разделение и упаковка модулей - это вопрос практичности развертывания и разработки.Кому еще понадобится код?Если я хочу изменить функциональность Y, все ли в пакете X?

Предупреждение: образец приложения упакован в одно приложение, чтобы его было легко использовать в качестве инструмента обучения,Но вот некоторые рекомендации, использующие его в качестве примера и делающие вид, что он реальный. Я сделаю некоторые предположения об этом в вакууме в иллюстративных целях, но ответственный специалист DDD схватит эксперта по домену и проведет интервью с разработчиком.команда для проверки любых предположений о домене, границах контекста и взаимосвязи между этими контекстами. Вы не можете использовать DDD в одиночку.

Правильное моделирование

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

  • Бронирование
  • Маршрутизация
  • Сторонние поставщики / Порты /Корабли и т. Д.

Если вы заметили, что они четко отделены от корневых пакетов Java

  • se.citerus.dddsample
  • com.pathfinder
  • com.aggregator

Уровни в основном предназначены для облегчения связи между этими контекстами и для отделения проблем инфраструктуры от работы в домене, что делает тестирование проще и обязанности домена более простыми.Инфраструктура важна, но тот факт, что пример приложения использует XML здесь и JMS там и в спящем режиме, есть второстепенные проблемы для моделирования домена.

В примере приложения это разделение становится очень ясным, легко увидеть, где Совокупные корни :

  • Грузовые
  • HandlingEvent
  • Местоположение
  • Рейс

Разбивать java-пакеты Aggegrate Roots - это хорошая практика.Leg не означает ничего за пределами агрегата Cargo, расписание - ничего за пределами агрегата Voyage, HandlingHistory - ничего за пределами агрегата HandingEvent.Хорошей практикой является сохранение доменной модели изолированной и тестируемой без инфраструктуры.Но вы, вероятно, не расширили бы эту развязку до уровня модуля.Не будет правилом говорить, что все ваши доменные объекты находятся в одном банке, а вся ваша инфраструктура - в другом.Бремя разработки и версии может стать болезненным.

Определение ограниченного контекста

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

Два контекста Booking иМаршрутизация осуществляется в тесном партнерстве , где они поддерживают общий интерфейс между двумя моделями ребер и узлов, а также маршрутами и ногами.Этот перевод поддерживается между моделями, которые управляются в ExternalRoutingService, где TransitPath становится маршрутом.Очевидно, что это очень важная точка интеграции, которая должна быть хорошо проработана в тестах и ​​управляться с помощью Непрерывная интеграция

Другой контекст - это сторонняя интеграция, которая сообщает HandingEvents приложению о состоянии груза.Это достигается с помощью шаблона под названием Опубликованный язык .Короче говоря, нам все равно, как выглядят модели грузов третьих сторон, если они сообщают нам о событиях обработки в соответствии с нашей спецификацией публикации XML HandlingReport.

Взаимосвязь между сторонним контекстом и доменом бронирования называется Conformist , они предоставляют данные в соответствии с нашей определенной спецификацией, мы не изменяем наши модели, чтобы им было проще.Бремя на них, чтобы соответствовать нам.Тем не менее, я догадываюсь о ситуации, возможно, существует очень важный поставщик, и они фактически определяют модель XML, а не нас.Только интервью с вымышленной командой может действительно характеризовать это.

Так что в итоговой группе все классы тесно связаны с Агрегатом (возможно, тот же пакет).Четко определите границы контекста и убедитесь, что есть четкая точка интеграции, определите взаимосвязь контекстов Партнерство, Общее ядро, Опубликованный язык, Open Host Service, Conformist и т. Д.

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

Ищите модули в ограниченном контексте

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

Ищите модули в вашем контексте.Они являются наиболее естественными кандидатами для отдельных модулей, и разделение может помочь более строго соблюдать и документировать границы контекста.Однако, как и многие другие разработки программного обеспечения, это не сложное и быстрое правило, которое будет зависеть от конкретного случая.Я могу себе представить и видел / писал приложения, которые имеют разные модели записи и модели чтения (думаю, нормализованные и денормализованные для, скажем, отчетности) и контексты для каждого из них, которые по практическим соображениям все еще могут быть упакованы в один модуль.

Еще один момент - опасайтесь совместного использования Агрегированных Корней между контекстами , это шаблон общего ядра DDD, и его следует использовать очень экономно, так как он может быстро скатиться в модель большого беспорядочного домена, которая не удовлетворяет потребностям любогоконтекст хорошо.Обратите внимание, что пример приложения не разделяет модели между RoutingService и BookingService.Помещение всех корней агрегатов домена в один модуль может непреднамеренно стимулировать эту практику.

...