Exemple d' application PHP utilisant les principes de conception pilotée par domaine (DDD) et de séparation des responsabilités des requêtes de commande (CQRS) en gardant le code aussi simple que possible.
Jetez un oeil, jouez et amusez-vous avec ça. Les étoiles sont les bienvenues
Voir la démo · Signaler un bug · Demander une fonctionnalité
git clone https://github.com/CodelyTV/php-ddd-example php-ddd-example
cd php-ddd-example
cp .env .env.local
) si vous souhaitez modifier un paramètremake build
make deps
make test
Ce projet tente d'être une plateforme MOOC (Massive Open Online Course). Il est découplé de tout framework, mais il possède quelques implémentations Symfony et Laravel.
Ce référentiel suit le modèle de l'architecture hexagonale. De plus, il est structuré à l'aide modules
. Avec cela, nous pouvons voir que la structure actuelle d’un contexte borné est :
$ 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
Nos référentiels essaient d'être aussi simples que possible et ne contiennent généralement que 2 méthodes search
et save
. Si nous avons besoin d'une requête avec plus de filtres, nous utilisons le modèle Specification
également connu sous le nom de modèle Criteria
. Nous ajoutons donc une méthode searchByCriteria
.
Vous pouvez voir un exemple ici et sa mise en œuvre ici.
Vous pouvez voir un exemple d'agrégat ici. Tous les agrégats doivent étendre AggregateRoot.
Il existe 1 implémentations du bus de commande.
Le Query Bus utilise le Symfony Message Bus.
Le bus d'événements utilise le bus de messages Symfony. Le bus MySql utilise un MySql+Pulling comme bus. Le bus RabbitMQ utilise l'extension RabbitMQ C.
Chaque fois qu'un événement de domaine est publié, il est exporté vers Prometheus. Vous pouvez accéder au panneau Prometheus ici.
Il manque certaines choses (ajouter du swagger, améliorer la documentation...), n'hésitez pas à ajouter ceci si vous le souhaitez ! Si vous souhaitez des directives, n'hésitez pas à nous contacter :)
Ce code a été présenté dans la discussion Du code couplé au framework aux #microservices via #DDD et les doutes ont reçu une réponse dans la vidéo DDD et CQRS : Preguntas Frecuentes.
Utilisé dans les cours CodelyTV Pro :