За многие годы, что разработчики воюют со сложностью, было разработано немало архитектурных подходов. Хотелось бы подробно рассмотреть один очень важный подход, который называется DDD - Domain Driven Development. Этот подход снискал наибольшую популярность при разработке корпоративных приложений со сложной бизнес-логикой. Дело в том, что в подобных случаях сложным и запутанным может быть не только код и его архитектура, но и сама бизнес-логика. Она может изобиловать большим количеством специфических терминов, различных подобластей, что вносит дополнительную сложность. Именно для решения этой проблемы был придуман DDD. DDD вводит определенный терминологический словарь:
Domain - предметная область. Это именно то, что мы будем автоматизировать/разрабатывать. Включает в себя:
- Core - основная часть бизнеса, наиболее важная
- Supporting - второстепенная часть бизнеса
- Generic - общая часть бизнеса, которая может быть автоматизирована сторонними решениями
Subdomain - субдомен предметной области. Иногда доменная область оказывается слишком огромной и ее дробят на несколько субдоменных областей, каждая из которых может содержать свой специфический Ubiqutuous language и свою domain model.
Ubiqutuous language - язык предметной области. Язык включает в себя сущности предметной области и позволяет описывать поведение системы на языке бизнеса.
Bounded Context - часть домена, которую покрывает наше программное решение. Покрыть Domain полностью не представляется возможным, поскольку он является чем-то реально существующим, вместо этого мы автоматизируем его ограниченную часть. Bounded context должен быть ровно таким, чтобы ubiquitous language был полным, непротиворечивым, однозначным, консистентным»
Entity - сущность предметной области. Например, если в коде будет два объекта Product с одним и тем же полем id, но различной ценой, это будет один и тот же объект Entity. Таким образом, Entity - это понятие именно из предметной области, а не объект в программном коде.
Value Object - объект, содержащий данные об Entity. Value Object-ы неизменяемы (имеют нулевой жизненный цикл). В коде мы можем их создавать, отправлять, удалять, но не должны вносить в них изменения. Для этого предназначены Entity.
Aggregate - набор тесно связанных между собой сущностей. Например, агрегат может представлять собой взаимосвязь нескольких таблиц (Order и Items). К составляющим агрегат сущностям нельзя обращаться напрямую из-вне. Aggregate, как и Entity определяется по идентификатору, а также является границей для транзакций.
Service - имплементирует процесс предметной области. Хотя сервис и может быть классом, он не представляет собой экземпляр чего-либо. Сервис инкапсулирует в себе бизнес-логику для построения многослойной архитектуры. Сервисы должны быть stateless. Сервисы могут обращаться к репозиториям и другим сервисам.
Repository - интерфейс доступа к данным (БД), который не зависит от конкретной реализации БД
DTO - data transfer object - предназначен для передачи данных между слоями приложения.
- DDD - это про язык, а не про технологии (используйте единый язык предметной области для общения с бизнесом и командой)
- один bounded context на один микросервис
- доменная модель и бизнес логика должны использовать ubiqutous language
- entity должны соответствовать сущностям реального мира
- доменная логика не должна зависеть от инфраструктуры или представления
- предпочитайте Value Object-ы вместо Entity
- Предпочитайте объекты-значения сущностям при моделивании домена
https://habr.com/ru/company/jugru/blog/440772/ https://fwdays.com/en/event/php-fwdays-17/review/domain-driven-design https://habr.com/ru/post/316890/