L'architecture des services MVC est si courante dans les projets Symfony qu'elle semble être la seule solution. C'est simple, familier et cela fonctionne... jusqu'à ce que ce ne soit plus le cas. À mesure que votre projet se développe, des fissures commencent à apparaître : votre logique métier est partout, le comportement des applications n'est pas clair et la maintenance du code devient pénible. Bien qu’il s’agisse de l’approche la plus courante, Symfony ne vous oblige pas à vous y tenir.
Et s'il y avait une meilleure solution ?
À mesure qu'un projet se développe, la logique métier a tendance à s'étendre à l'ensemble de la base de code. Chaque couche du projet (contrôleurs, services, formulaires, entités) finit par contenir des éléments du modèle de domaine. Cela rend de plus en plus difficile de se concentrer sur une partie spécifique.
Lorsque votre architecture est organisée autour de couches techniques, il devient plus difficile d'identifier des frontières claires entre différents contextes à mesure que le projet se développe. Ce manque de clarté peut conduire à des problèmes de code et de maintenance étroitement liés.
Étant donné que l'architecture par défaut met l'accent sur les couches techniques, il devient assez difficile de comprendre les comportements du projet. Vous pouvez déduire que certaines entités sont gérées par des services spécifiques ou deviner le schéma de la base de données, mais les comportements réels du projet, qui sont les aspects les plus importants, restent flous et implicites.
Lorsque la logique métier est dispersée dans le projet et mélangée aux détails de mise en œuvre, il devient difficile de les faire évoluer indépendamment. Au fil du temps, le cycle de vie de la logique métier a tendance à être beaucoup plus long que celui des détails de mise en œuvre (tels que les frameworks, les API tierces ou les bases de données). Cette inadéquation vous oblige à réécrire de grandes portions de code chaque fois que des modifications, même mineures, se produisent dans une dépendance.
Pour faciliter la concentration sur la logique métier en cas de besoin, la première étape consiste à l'isoler du reste du projet. Pour y parvenir, créez un dossier Domaine. Ce dossier devient le cœur du projet, où la logique métier est modélisée à l'aide d'objets PHP purs, sans dépendances sur les détails d'implémentation. Alors que le reste du projet dépend de ce dossier, le dossier Domaine ne dépend de personne.
Dans le dossier Domaine, les fichiers doivent être regroupés par objectif de domaine plutôt que par objectif technique. Cela signifie qu'il n'y a pas de dossiers Entités, Services ou Contrôleurs ici, uniquement des noms de dossiers qui correspondent à des fonctionnalités ou à des concepts de domaine.
L'aspect le plus important d'un projet est ce qu'il fait, les actions qu'il peut gérer. Ces actions représentent les comportements du projet et doivent constituer le seul moyen d'accéder à la logique métier. Pour refléter cela, créez un dossier Application qui présente explicitement tous les comportements du projet. Par exemple, en tant que nouveau développeur sur le projet, je devrais pouvoir comprendre d'un coup d'œil ce que le projet est capable de faire en consultant ce dossier.
Avec les dossiers App et Domain, il devient facile de se concentrer sur la logique métier. Cependant, à un moment donné, cette logique métier doit interagir avec des systèmes externes. Pour gérer cela, créez un troisième dossier appelé Infrastructure, qui contient tous les détails d'implémentation tels que le code spécifique au framework, les connexions à la base de données et les bibliothèques.
Les fichiers du dossier Infrastructure dépendent des fichiers de l'application et du domaine. Par exemple, ils peuvent appeler un gestionnaire d'application à partir du dossier App ou implémenter une interface définie dans le dossier Domaine.
Concrètement, dans Symfony, cela implique de modifier le dossier Controller et de déclarer quels services implémentent quelles interfaces.
# config/routes.yaml controllers: resource: path: ../src/Catalog/Infrastructure/Controller/ namespace: App\Catalog\Infrastructure\Controller type: attribute
Au fur et à mesure que votre projet évolue, vous remarquerez peut-être que certaines parties de la logique métier méritent leur propre espace dans l'architecture. Un bon indicateur est le moment où le même terme commence à avoir des significations différentes selon le contexte. Par exemple, le mot Produit peut faire référence à un produit d'usine, un produit d'entrepôt ou un produit de commerce électronique, chacun nécessitant son propre modèle. Un objet divin peut également être un bon indicateur ; la classe User a souvent ce type de problème dans les projets Symfony.
Quand cela se produit, il est temps de l’extraire et de laisser sa logique métier évoluer de manière indépendante.
Certains contextes constitueront le cœur de votre projet, tandis que d'autres le soutiendront. Les contextes génériques, comme Auth, peuvent utiliser une architecture plus simple car ils ne sont pas centraux dans votre domaine
Dans cette image, nous pouvons voir que le contexte Auth utilise une structure Symfony standard, les contextes Order et Catalog utilisent une architecture centrée sur le domaine et le contexte Shipping utilise une architecture centrée sur les fonctionnalités.
Si un contexte spécifique se développe au point où il doit évoluer de manière indépendante, envisagez de le diviser en une unité de déploiement distincte.
Cependant, ne vous précipitez pas dans cette étape. Commencez par rendre votre projet modulaire, et si vous remarquez qu'un contexte doit évoluer individuellement, déployez-le séparément.
Divisez la base de code uniquement si des problèmes organisationnels surviennent, tels que deux équipes ayant du mal à collaborer sur la même base de code.
En explorant ces solutions, nous avons appliqué plusieurs concepts artisanaux. Nommons-les et expliquons-les brièvement, afin que vous puissiez approfondir chacun d'eux.
Derrière ce terme inhabituel se cache un concept très simple. Le langage omniprésent est le vocabulaire que votre équipe utilise pour décrire votre modèle de domaine. Ce vocabulaire doit être documenté et utilisé de manière cohérente partout, dans les conversations sur les produits, la base de code et au-delà.
Concrètement, créez un fichier markdown à la racine d'un Bounded Context et rassemblez des personnes produit, des experts du domaine et des équipes techniques pour définir chaque concept de votre projet.
Un contexte délimité définit la frontière linguistique au sein de votre projet, séparant les parties du système où la langue omniprésente ne s'aligne plus. Des outils tels que les cartes contextuelles et l'Event Storming peuvent aider à identifier ces limites.
Un contexte délimité est un concept abstrait ; il peut être implémenté de plusieurs manières, d'un simple dossier dans un monolithe modulaire à un cluster dans une architecture de microservices.
Toutes ces architectures visent à isoler la logique métier des détails de mise en œuvre. Que vous utilisiez des ports et des adaptateurs, une architecture hexagonale ou une architecture propre, l'idée principale est de rendre le cadre de logique métier indépendant et facile à tester.
Une fois que vous avez cela à l’esprit, il existe un spectre complet d’implémentations, et la meilleure dépend de votre contexte et de vos préférences. Un avantage majeur de cette architecture est qu'en isolant votre logique métier, elle permet des tests beaucoup plus efficaces.
L'idée d'organiser des dossiers et des fichiers pour « crier » la logique métier est connue sous le nom de Screaming Architecture. Ce concept souligne que la structure de votre code doit rendre immédiatement clair l’objectif du projet. L'objectif est qu'un nouveau développeur comprenne en un coup d'œil ce que fait le projet.
Je recommande fortement de lire l'article d'Oncle Bob sur le sujet : sa comparaison avec un plan de maison est particulièrement instructive.
Le découpage vertical organise votre projet par fonctionnalités, permettant à chaque fonctionnalité d'évoluer indépendamment. Il vous permet d'appliquer différentes architectures à différentes fonctionnalités en fonction de la complexité et de la maturité.
Bien que l'idée soit intéressante, elle nécessite des ingénieurs hautement qualifiés pour mettre en œuvre et maintenir efficacement une telle architecture.
La façon dont vous structurez votre projet Symfony a un impact profond sur son évolutivité, sa maintenabilité et sa clarté. En isolant votre logique métier et en rendant les comportements explicites, vous créerez un système plus facile à comprendre et à évoluer.
Si ces idées vous sont nouvelles, ne vous inquiétez pas, la création logicielle est un voyage, pas une destination. Les concepts peuvent sembler écrasants au début, mais chacun vous aidera à apporter plus de valeur à votre entreprise.
Vous avez des questions ou souhaitez partager votre expérience ? Déposez-les dans les commentaires ! Et restez connectés pour le prochain article ?
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!