Введение

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

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

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

Поэтому для разработчиков важно принять более бизнес-ориентированный подход к разработке, и один из способов добиться этого — это проектирование, управляемое предметной областью (DDD). Сосредоточив внимание на предметной области и моделируя ее с помощью объектов и служб предметной области, DDD может помочь разработчикам создавать более удобные в сопровождении, эффективные и адаптируемые веб-службы.

Что такое доменно-ориентированный дизайн?

Domain Driven Design — это подход к разработке программного обеспечения, который подчеркивает важность понимания предметной области бизнеса. Он состоит из двух основных частей: стратегической и тактической.

Стратегическое проектирование на основе предметной области связано с определением общей архитектуры системы. Это включает определение основных бизнес-доменов и поддоменов, а также определение контекста, в котором будет использоваться система.

Tactical Domain Driven Design занимается реализацией системы на основе стратегических проектных решений. Это включает в себя определение объектов предметной области (агрегатов, сущностей), сервисов и репозиториев, а также реализацию бизнес-логики таким образом, чтобы это соответствовало решениям по стратегическому проектированию.

Компоненты тактического проектирования, ориентированного на предметную область

Tactical DDD ориентирован на внедрение системы на основе стратегических конструкторских решений. Следующая диаграмма представляет собой изображение типичной проектной схемы, управляемой доменом, которая также реализует то, что называется CQRS (разделение ответственности команд и запросов):

Агрегаты

Агрегаты — это кластеры связанных объектов, которые рассматриваются как единое целое. Они представляют собой границу, в пределах которой поддерживается согласованность. Все изменения объектов в агрегате должны соответствовать правилам агрегата.

Сущности

Сущности — это объекты, которые имеют уникальную идентичность. Они отличаются от других объектов своей идентичностью, а не атрибутами. Сущности могут иметь жизненный цикл, выходящий за рамки одной транзакции.

💡 В чем разница между агрегатами и сущностями? Разница между ними заключается в том, что агрегаты могут жить без других сущностей, в то время как сущность должна находиться в агрегате.

⚠️ Имейте в виду, что, хотя у агрегатов есть дочерние сущности, они не должны располагаться слишком глубоко. Если вы обнаружите, что агрегат содержит много дочерних элементов, вы должны пересмотреть, могут ли дочерние элементы технически жить без родителя.

Ценные объекты

Объекты-значения — это объекты, не имеющие собственной идентичности. Они определяются своими атрибутами и могут сравниваться с другими объектами-значениями на основе этих атрибутов.

Службы приложений

Службы приложений отвечают за обработку запросов, поступающих из внешнего мира, и являются точкой входа для доменного уровня. Они координируют выполнение доменных служб и репозиториев для выполнения запрошенной операции.

Службы приложений отвечают за проверку ввода, авторизацию и обработку ошибок. Они также отображают ввод/вывод в/из объектов предметной области или примитивов.

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

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

Службы приложений также отвечают за обработку транзакций базы данных. Они обеспечивают успешное выполнение всех операций в рамках одной транзакции или откат в случае сбоя. Границы транзакций определяются на уровне службы приложений, гарантируя, что уровень предметной области не связан с деталями персистентности. Такое разделение задач позволяет улучшить ремонтопригодность и тестируемость, а также улучшить масштабируемость и производительность.

Доменные службы

Сервисы — это операции, не связанные с каким-либо конкретным объектом. Они используются для выполнения операций, выходящих за границы агрегатов, или для выполнения операций, которые не соответствуют обязанностям какого-либо конкретного объекта.

Репозитории

Репозитории предоставляют способ хранения и извлечения объектов домена. Они действуют как мост между моделью предметной области и уровнем постоянства.

Чтение и запись репозиториев

В тактическом DDD репозитории предоставляют способ хранения и извлечения объектов предметной области. Они действуют как мост между моделью предметной области и уровнем постоянства. Однако не все репозитории одинаковы.

В некоторых случаях может быть полезно иметь отдельные репозитории для чтения и записи. Репозиторий записи отвечает за сохранение изменений в объектах домена, а репозиторий чтения отвечает за извлечение данных из базы данных.

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

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

Используя отдельные репозитории для чтения и записи, мы можем оптимизировать приложение для различных вариантов использования, сохраняя при этом согласованное представление данных. Это может привести к более производительному и масштабируемому приложению, а также упростить поддержку и расширение кодовой базы.

События домена

События предметной области используются для передачи изменений между агрегатами. Они используются для отделения агрегатов друг от друга и обеспечения распространения изменений по всей системе.

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

Команды

В дополнение к событиям предметной области другим важным компонентом проектирования, управляемого предметной областью, являются команды. Команды используются для представления действия, которое должно быть выполнено системой. Они похожи на события предметной области тем, что используются для связи между различными частями модели предметной области, но обычно используются для инициирования действия, а не для уведомления об изменении. Команды обычно отправляются с прикладного уровня на уровень домена и используются как доменными службами, так и агрегатами.

Заключение

Domain Driven Design — это мощный подход к разработке программного обеспечения, который может помочь разработчикам создавать более удобные в сопровождении, эффективные и адаптируемые веб-сервисы. Сосредоточив внимание на предметной области и моделируя ее с помощью объектов и служб предметной области, DDD может помочь разработчикам создавать бизнес-ориентированные приложения, которые легче поддерживать и расширять.

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

Хотя многое еще предстоит узнать о DDD, мы надеемся, что это руководство дало вам хорошее введение в эту тему и вдохновило вас узнать больше о том, как его можно применять в ваших собственных проектах.