Bounded Context
Большие проекты часто содержат несколько реализаций одной и той же абстракции. Попытки напрямую объединить такие модели порождают нечитабельный код и ошибки.
Явно определите контекст для каждой конкретная модель. Устанавите границы в терминах деления разработчиков на команды, использования в специфических частях системы или физической инфраструктуры (таких как схема базы данных, файлы и т.д.)
Дайте контексту явное наименование и сделайте это имя частью общего языка.
Удерживайте модель "чистой" внутри ограниченного контекста. Не беспокойтесь о "двойниках" вне этого контекста и о применении вашей модели за границами ее контекста.
Continuous Integration
Когда множество людей работают, используя один и тот же ограниченный контекст, существует выраженная тенденция к фрагментации моделей данного контекста.
Для борьбы с подобным расщиплением используется непрерывная интеграция: все усилия внутри ограниченного контекста объединяются достаточно часто для того чтобы любое расщепление модели было немедленно замечено и устранено.
Context Map
Каждый ограниченный контекст не способен охватить все приложение целиком. Поэтому контексты вынуждены взаимодействовать друг с другом.
Определите точки соприкосновения между контекстами. Опишите явные преобразования для любых взаимодействий контекстов.
Shared Kernel
Иногда непрерывная интеграция требует чрезмерных усилий. В этом случае ограниченный контекст может быть разделен на две части с формированием двух отдельных команд разработчиков.
Однако усилия для создания и поддержания слоев трансляции между контекстами могут оказатся больше усилий, которые бы тратились на непрерывную интеграцию в случае, если бы контекст остался единым.
Выделите общее ядро - некоторое подмножество доменной модели и соответствующего инфраструктурного кода для совместного использования двумя командами. Этот код имеет особый статус и не может быть изменен без консультаций между командами.
Customer/Supplier Development Teams
Часто две подсистемы одного проекта взаимодействуют ассиметрично: первая полностью зависит от результатов работы второй, а вторая даже ничего не знает о первой.
Распространенный пример: одна команда работает над подсистемой операционного уровня (сбор и формализация данных), в то время как вторая занимается анализом полученных данных.
Установите между двумя командами отношения типа заказчик/разработчик. На всех этапах разработки считайте представителей зависимой команды заказчиками.
Conformist
В случае если две команды находятся во взаимоотношениях заказчик/разработчик при которых разработчик не желает удовлетворять нужды заказчика -- заказчик беспомощен.
Безоговорочно примите модели поставщика. Хотя вы не получите идеальную модель для ваших целей, вы сильно упростите интеграцию.
Вы также будете вынуждены использовать общий язык команды поставщика.
Anticorruption Layer
Новые системы почти всегда должны интегрироваться с унаследованными. Модель унаследованной системы в большинстве случаев слаба. Однако Вы не можете избежать интеграции.
Создайте изолирующий слой, предоставляющий API в терминах доменной модели новой системы. Этот слой будет взаимодействовать с с унаследованными системами, используя их интерфейс и не требую их модификации.
Separate Ways
Интеграция всегда имеет цену. Иногда выигрыш не покрывает расходы.
Определите ограниченный контекст и полностью исключите интеграцию. Найдите простое решение, "заточенное" для данного контекста.
Open Host Service
Обычно ограниченный контекст имеет по слою трансляции на каждый из компонентов требующих интеграции. Когда контекст интегрируется со множеством других, выстраивание слоя трансляции для каждого отдельного случая неприемлемо.
Разработайте протокол в виде набора сервисов, которые определят доступ к данной подсистеме извне. Все нуждающиеся в интеграции должны использовать этот протокол.
Published Language
В ситуации когда два ограниченных контекста вынуждены сосуществовать и обмениваться информацией, процесс трансляции сам по себе может быть сложен и трудно документируем.
При этом прямая трансляция между языками может оказаться не самым лучшим решением.
Используйте хорошо документированный и свободно доступный язык, выразительно передающий абстракции доменной области.
Core Domain
В большой системе так много абсолютно необходимых компонентов, что главная функциональная часть приложения может оказаться размытой и заброшенным.
Найдите центральную область модели и в дальнейшем четко отличайте ее от массы вспомогательного кода. Выставте для нее наивысший приоритет. Стремитесь к тому, чтобы центр модели был компактным. Над центральным доменом должны трудится лучшие разработчики проекта.
Generic Subdomains
Любая систима содержит код, который решает достаточно общие и повторяющиеся от приложения к приложению задачи. Код этот, жизненно необходимый для системы, в то же время не составляет центра доменной области. Не ради этого кода затевался проект.
Идентифицируйте поддомены не имеющие прямого отношения к сердцу проекта. Выделите их в обособленные модули. В этих модулях ни должно остаться и следа от центра доменной области. Избегайте назначать ваших основных разработчиков на задачи, связанные с этими поддоменами.
Cohesive Mechanisms
Иногда вычисления достигают того уровня сложности, когда начинают закрывать собой дизайн модели. Концептуальное "что" нельзя увидеть за подробностями "как".
Выдилите самодостаточные вычисления в отдельный легковесный фрэймворк. В частности попытайтесь найти формализмы или хорошо известные алгоритмы. Производите доступ к фрэймворку через интерфейс, раскрывающий намерения, желательно в максимально декларативном стиле.
Материал был доложен в рамках июльской встречи cofee'n'code в Донецке. Благодарю моего содокладчика Алексанра Шишкина за конструктивное сотрудничество и интересный доклад.
No comments:
Post a Comment