Exemplo de um aplicativo PHP usando os princípios Domain-Driven Design (DDD) e Command Query Responsibility Segregation (CQRS), mantendo o código o mais simples possível.
Dê uma olhada, brinque e divirta-se com isso. Estrelas são bem-vindas
Ver demonstração · Relatar um bug · Solicitar um recurso
git clone https://github.com/CodelyTV/php-ddd-example php-ddd-example
cd php-ddd-example
cp .env .env.local
) se desejar modificar algum parâmetromake build
make deps
make test
Este projeto tenta ser uma plataforma MOOC (Massive Open Online Course). É desacoplado de qualquer framework, mas possui algumas implementações de Symfony e Laravel.
Este repositório segue o padrão de Arquitetura Hexagonal. Além disso, é estruturado usando modules
. Com isso, podemos ver que a estrutura atual de um Contexto Delimitado é:
$ 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
Nossos repositórios tentam ser o mais simples possível, geralmente contendo apenas 2 métodos search
e save
. Caso precisemos de alguma consulta com mais filtros utilizamos o padrão Specification
também conhecido como padrão Criteria
. Portanto, adicionamos um método searchByCriteria
.
Você pode ver um exemplo aqui e sua implementação aqui.
Você pode ver um exemplo de agregado aqui. Todas as agregações devem estender AggregateRoot.
Existem 1 implementações do barramento de comando.
O Query Bus usa o Symfony Message Bus.
O Event Bus usa o Symfony Message Bus. O barramento MySql usa um MySql+Pulling como barramento. O barramento RabbitMQ usa a extensão RabbitMQ C.
Cada vez que um evento de domínio é publicado, ele é exportado para o Prometheus. Você pode acessar o painel do Prometheus aqui.
Faltam algumas coisas (adicionar arrogância, melhorar a documentação...), fique à vontade para adicionar se quiser! Se você quiser algumas orientações, não hesite em nos contatar :)
Este código foi mostrado no From framework acoplado código a #microservices através do #DDD talk e dúvidas foram respondidas no vídeo DDD y CQRS: Preguntas Frecuentes.
Usado nos cursos CodelyTV Pro: