Предметно-ориентированное проектирование.
Подход к разработке ПО, ставящий в центр проектирования богатую модель бизнес-домена, выраженную на языке, общем для инженеров и экспертов предметной области.
##Intent
Справляйтесь со сложностью в самом сердце ПО, явно моделируя бизнес-домен и удерживая эту модель — и код, который её выражает, — в тесном согласии с языком людей, понимающих домен.
##Problem
По мере роста системы бизнес-правила склонны рассеиваться по контроллерам, сервисам и запросам к базе данных. Код отдаляется от того, как бизнес на самом деле говорит о своей работе, поэтому каждый разговор нуждается в переводе, а каждое изменение рискует нарушить правило, о котором никто не помнил.
Проектирование, центрированное на данных, усугубляет это: модели становятся анемичными мешками геттеров и сеттеров, инварианты не живут нигде конкретно, и система медленно превращается в "большой ком грязи", к которому осмеливаются прикасаться лишь немногие.
##Solution
Предметно-ориентированное проектирование атакует проблему на двух уровнях.
Стратегическое проектирование делит большой домен на ограниченные контексты — явные границы, внутри которых модель и её язык согласованы, — и отображает связи между ними. Каждый контекст волен моделировать одно и то же понятие по-разному там, где бизнес действительно видит его по-разному.
Тактическое проектирование строит богатую модель внутри контекста из небольшого набора строительных блоков и настаивает на едином языке: одни и те же термины появляются в разговорах, в модели и в коде.
##Structure
Тактические строительные блоки:
- Сущности — объекты, определяемые идентичностью, которая сохраняется во времени (
Customer,Order). - Объекты-значения — неизменяемые объекты, определяемые своими атрибутами (
Money,Address). - Агрегаты — кластеры сущностей и объектов-значений с единственным корнем агрегата, который охраняет инварианты кластера и является единственной точкой входа для изменений.
- Репозитории — коллекциеподобные интерфейсы, загружающие и сохраняющие целые агрегаты, скрывая детали хранения.
- Доменные сервисы — операции без состояния, которые естественно не принадлежат одной сущности.
- Доменные события — записи о чём-то значимом, что произошло в домене.
Стратегические блоки — ограниченный контекст и карта контекстов — организуют эти модели по командам и подсистемам.
##Applicability
- Применяйте его, когда основная сложность в бизнес-правилах, а не в технологии — логистика, финансы, страхование, планирование.
- Применяйте его, когда нескольким командам нужно прийти к согласию об общем, развивающемся понимании домена.
- Избегайте его для простых CRUD-приложений или приложений ввода данных, где накладные расходы на моделирование дают мало.
##How to Implement
- Беседуйте с экспертами предметной области и выделяйте единый язык; записывайте термины и их значения.
- Определите ядро домена — часть, дающую конкурентное преимущество, — и сосредоточьте усилия моделирования там.
- Разделите домен на ограниченные контексты и нарисуйте карту контекстов с их взаимосвязями.
- Внутри контекста моделируйте агрегаты так, чтобы каждый обеспечивал свои инварианты в одной транзакции.
- Загружайте и сохраняйте агрегаты через репозитории; публикуйте доменные события о том, что важно другим контекстам.
- Постоянно совершенствуйте — модель никогда не «готова», она развивается по мере углубления понимания.
##Pros & Cons
- Удерживает код в согласии с бизнесом, поэтому изменения чисто отображаются на требования.
- Изолирует сложность за ограниченными контекстами.
- Общий язык снижает недопонимание между инженерами и экспертами.
- Богатая доменная логика отвязана от инфраструктуры и легко покрывается модульными тестами.
- Крутая кривая обучения и реальные вложения в моделирование домена.
- Избыточно для простых или преимущественно CRUD-приложений.
- Требует постоянного доступа к экспертам предметной области.
- При неправильном применении строительные блоки превращаются в церемонию без пользы.