Пример приложения PHP, использующего принципы доменно-ориентированного проектирования (DDD) и разделения ответственности за запросы команд (CQRS), позволяющие максимально упростить код.
Смотрите, играйте и получайте от этого удовольствие. Звезды приветствуются
Посмотреть демо · Сообщить об ошибке · Запросить функцию
git clone https://github.com/CodelyTV/php-ddd-example php-ddd-example
cd php-ddd-example
cp .env .env.local
), если вы хотите изменить какой-либо параметр.make build
make deps
make test
Этот проект пытается стать платформой MOOC (массовый открытый онлайн-курс). Он отделен от какой-либо инфраструктуры, но имеет некоторые реализации на Symfony и Laravel.
Этот репозиторий соответствует шаблону шестиугольной архитектуры. Кроме того, он структурирован с использованием modules
. При этом мы видим, что текущая структура ограниченного контекста:
$ tree - L 4 src
src
|-- Mooc // Company subdomain / Bounded Context: Features related to one of the company business lines / products
| ` -- Videos // Some Module inside the Mooc context
| |-- Application
| | |-- Create // Inside the application layer all is structured by actions
| | | |-- CreateVideoCommand .php
| | | |-- CreateVideoCommandHandler .php
| | | ` -- VideoCreator .php
| | |-- Find
| | |-- Trim
| | ` -- Update
| |-- Domain
| | |-- Video .php // The Aggregate of the Module
| | |-- VideoCreatedDomainEvent .php // A Domain Event
| | |-- VideoFinder .php
| | |-- VideoId .php
| | |-- VideoNotFound .php
| | |-- VideoRepository .php // The `Interface` of the repository is inside Domain
| | |-- VideoTitle .php
| | |-- VideoType .php
| | |-- VideoUrl .php
| | ` -- Videos .php // A collection of our Aggregate
| ` -- Infrastructure // The infrastructure of our module
| |-- DependencyInjection
| ` -- Persistence
| ` -- MySqlVideoRepository .php // An implementation of the repository
` -- Shared // Shared Kernel: Common infrastructure and domain shared between the different Bounded Contexts
|-- Domain
` -- Infrastructure
Наши репозитории стараются быть максимально простыми и обычно содержат только два метода: search
и save
. Если нам нужен запрос с большим количеством фильтров, мы используем шаблон Specification
, также известный как шаблон Criteria
. Поэтому мы добавляем метод searchByCriteria
.
Вы можете увидеть пример здесь и его реализацию здесь.
Посмотреть пример агрегата можно здесь. Все агрегаты должны расширять AggregateRoot.
Существует 1 реализация командной шины.
Шина запросов использует шину сообщений Symfony.
Шина событий использует шину сообщений Symfony. Шина MySql использует MySql+Pulling в качестве шины. Шина RabbitMQ использует расширение RabbitMQ C.
Каждый раз, когда событие домена публикуется, оно экспортируется в Prometheus. Вы можете получить доступ к панели Prometheus здесь.
Некоторых вещей не хватает (добавьте чванства, улучшите документацию...), не стесняйтесь добавлять это, если хотите! Если вам нужны какие-то рекомендации, свяжитесь с нами :)
Этот код был показан в разделе «От кода, связанного с инфраструктурой, до #микросервисов через #DDD», а также в видео «DDD и CQRS: Preguntas Frecuentes».
Используется в курсах CodelyTV Pro: