Теория может привести к приобретению практического опыта. Однако теория без практики не даст реального понимания того, что и как делается.
Чтобы постичь все до конца и почувствовать себя уверенно в какой-то сфере, нужно пробовать свои силы и заниматься практическим делом.
В полной мере это относится к предметно-ориентированному проектированию (Domain Driven Design, DDD). Можно читать многочисленные статьи, смотреть видео и даже посещать семинары, но все это без личного практического опыта не даст настоящего понимания DDD.
Без непосредственного выполнения реальных проектов вы не узнаете:
- что такое бизнес-логика и техническая часть кода;
- как моделировать предметную область (домен);
- как создавать бизнес-потоки.
Совершая ошибки, принимая решения и сталкиваясь с трудностями, вы полностью освоите DDD-подход и научитесь применять его на практике.
Мы обретаем уверенность на практике, а не в теории. И только на практике мы узнаем, что такое DDD.
«Слои» правил
Одной из проблем, которая может помешать применить полученные знания на практике, являются «слои» правил для архитектуры DDD.
Вы можете столкнуться с такими утверждениями, как:
- нельзя использовать Active Record;
- нельзя создавать зависимости между слоями архитектуры;
- нужно сохранять объекты домена полностью чистыми.
Выполняя эти инструкции и выстраивая всю архитектуру на основе одного шаблона, например Active Record, вы просто отдалитесь от практического применения DDD. Следуя правилам DDD, вы должны будете убедить всех в проекте изменить способ отображения объектов в базе данных, а затем провести масштабный рефакторинг.
Разве это не глупо звучит?
В одном из первых DDD-проектов с моим участием было решено следовать правилу «Каждый слой архитектуры должен быть полностью несвязанным».
В результате огромное количество времени ушло на трансформацию между слоями. Вместо того чтобы лучше понять бизнес-логику, мы потратили время на соблюдение правила.
В конце концов все, кто участвовал в проекте, пришли к выводу: такой способ ведения дел усложняет разработку без особой пользы. Этот способ не оправдал себя в контексте нашей деятельности.
А контекст — самое важное. От того, в каком контексте вы работаете, зависит, имеет ли смысл данное правило или шаблон проектирования. Нужно разграничивать полезные правила, упрощающие разработку, от вредных, создающих трудоемкую практику.
Упрощение разработки высвобождает время, которое можно инвестировать в то, что важно — более глубокое понимание бизнес-логики.
Идеального подхода в проектировании не существует: он зависит от контекста, в котором его применяют. Поэтому есть проектирование, которое упрощает разработку, и то, что ее усложняет.
Бизнес-ориентированная архитектура
Мне хотелось представить в виде архитектуры только полезные шаблоны, правила и стили проектирования. В таком случае вместо повторной реализации этих шаблонов в проектах можно было бы просто использовать готовую архитектуру и с самого первого дня сосредоточиться на бизнес-аспектах.
Конечно, для этого нужны были шаблоны, которые решают такие проблемы, как отказоустойчивость, масштабируемость, восстанавливаемость на уровне архитектуры. Кроме того, нужно было абстрагироваться от таких вещей, как оркестровка и конфигурационный код.
Достичь этой цели позволило эффективное сочетание тактических (Tactical) шаблонов DDD с отказоустойчивым обменом сообщениями (Resilient Messaging). Такое сочетание я назвал бизнес-ориентированной архитектурой (Business Oriented Architecture).
Бизнес-ориентированная архитектура состоит из трех основных компонентов:
1. Отказоустойчивая служба сообщений (Resilient Messaging)
Большинству приложений необходим способ восстановления при возникновении сбоев. Это может понадобиться в случаях, когда интегрируемая система временно недоступна (например, Sendgrid, Stripe, Twilio), или когда в коде произошла ошибка, или когда часть собственной инфраструктуры вышла из строя.
Задача состоит в том, чтобы заставить систему в таких ситуациях самовосстанавливаться без ручного вмешательства. А если самовосстановление невозможно, как в случае с ошибкой в коде, то необходимо сохранить намерение того, что должно было произойти, обеспечивая возобновление потока при развертывании исправления.
Служба сообщений с использованием таких отказоустойчивых шаблонов, как Outbox, Idempotency, Delayed Retries и DLQ, доказала, что решает эти проблемы на корневом уровне.
2. Декларативная конфигурация (Declarative Configuration)
Даже при том, что служба сообщений заботится об отказоустойчивости, а также о масштабируемости, существует проблема траты слишком большого количества времени на конфигурацию либо службы сообщений, либо связанных с приложением элементов. Чем больше конфигураций, тем тяжелее их поддерживать, что чревато ошибками и трудоемкими обновлениями.
Решением этой проблемы являются разумные значения по умолчанию и декларативная конфигурация с атрибутами. Атрибуты помогают указать, «что должно произойти», и абстрагироваться от того, «как это должно произойти». В сочетании со службой сообщений это позволяет соединить все компоненты «под капотом» без единой строчки конфигурации. Декларативная конфигурация — мощный центр разработки, интуитивно понятный и легко изменяемый.
3. Строительные блоки (Building Blocks)
Между службой сообщений и компонентами более высокого уровня все еще существует необходимость в логике делегирования/оркестрации. Показательным примером этого являются часто используемые Command Handlers (обработчики команд). В большинстве DDD-приложений они выглядят одинаково: получить Aggregate, вызвать действие, сохранить его.
Такой код не приносит пользы бизнес-логике, поэтому его можно абстрагировать, используя два предыдущих компонента — декларативную конфигурацию и службу сообщений. Можно обозначить методы Aggregate непосредственно как Command Handlers, а логикой оркестровки пусть занимаются абстракции более низкого уровня.
Таким образом, остается только написать чистую бизнес-логику в Aggregate.
Бизнес-ориентированная архитектура — это комбинация корректно определенных шаблонов, используемых при разработке службы сообщений и DDD. Когда такие проблемы, как масштабируемость, отказоустойчивость и восстанавливаемость, решаются на уровне архитектуры, высвобождается много времени для сосредоточения на других вещах. Когда же к этому добавляются строительные блоки, такие как Aggregates (агрегаты), Sagas (саги) и Projections (проекции), связанные непосредственно со службой сообщений, остается написать не так уж много кода, помимо самой бизнес-логики.
При применении бизнес-ориентированной архитектуры большинство трудоемких проблем решается на уровне архитектуры. Это означает, что их не нужно будет решать снова. Так что код, который останется написать, — чистая бизнес-логика.
Более подробно изучить бизнес-ориентированную архитектуру позволит PHP-фреймворк Ecotone, созданный на основе этих концепций.
Резюме
Хотя теоретические знания о DDD очень ценны, только практический опыт применения позволяет по-настоящему воплотить его в жизнь.
Применение различных шаблонов и конструкций приводит к пониманию того, что не все из них полезны в конкретном контексте. Но те, которые докажут свою эффективность, сделают бизнес-логику более явной, а разработку — более продуктивной.
Бизнес-ориентированная архитектура позволяет совместно использовать определенные шаблоны, чтобы еще больше упростить разработку. А использование абстракций более высокого уровня, предоставляемых этой архитектурой, высвобождает огромное количество времени, которое можно уделить бизнес-аспектам кода.
Читайте также:
- Как перейти от монолитной системы к событийной
- 3 основных принципа несвязных приложений
- Чистая архитектура фронтенда: 7 советов для достижения успеха
Читайте нас в Telegram, VK и Дзен
Перевод статьи Dariusz Gafka: Practial Domain Driven Design