La Clean Architecture protège votre modèle. Encore faut-il en avoir un.
Introduction
La Clean Architecture est souvent présentée comme une solution universelle pour écrire du “bon code”. La promesse théorique est séduisante : un code découplé, maintenable dans le temps, indépendant de tout framework.
Mais derrière tout ça, une question reste rarement posée : qu’est-ce qu’on cherche vraiment à protéger ?
Tout dépend de la raison pour laquelle on l’adopte — elle peut être un cadre utile… ou devenir un dogme coûteux lorsqu’elle est appliquée sans discernement.
L’objectif ici est pragmatique : comprendre pourquoi la Clean Architecture existe, ce qu’elle protège réellement — et pourquoi ce qu’elle protège doit toujours passer avant elle.
Le faux problème : la séparation technique
On commence souvent par dire :
“Il faut séparer l’infrastructure du métier”
Et c’est vrai… mais insuffisant.
Prenons un exemple :
class PricingService {
public function __construct(
private WeatherApiInterface $weatherApi,
private MlApiInterface $mlApi
) {}
public function calculate(User $user) {
$weather = $this->weatherApi->get();
$score = $this->mlApi->predict($user);
}
}Ici, nous avons de l’injection de dépendances et une séparation correcte des appels externes.
Et pourtant, le problème principal n’est toujours pas résolu.
Bien que la DI facilite le découplage technique, elle ne résout pas la complexité structurelle qui émerge naturellement avec la croissance du projet.
Le vrai problème : la complexité métier
Avec le temps, le métier devient complexe.
Prenons un exemple métier :
if ($user->isLoyal()) {
$price -= 10;
}
if ($score > 0.8 && $weather->storm) {
$price += 50;
}
if ($market === ’aggressive’) {
$price *= 0.9;
}Soudain arrivent des règles alambiquées et réelles :
En mode “agressif”, le discount fidélité revient MAIS plafonné à 5% sauf en Allemagne
Autre exemple encore :
En Allemagne, en cas de tempête, les clients premium ne doivent PAS subir l’augmentation si leur score de risque est inférieur à X
Exemple concret que la DI ne résout pas :
if ($market === ’aggressive’) {
if ($user->isLoyal()) {
$discount = min(0.05, $this->loyaltyService->getDiscount($user));
if ($user->country !== ’DE’) {
$price -= $discount * $price;
}
}
}
if ($country === ’DE’ && $weather->storm && $user->isPremium() && $score < X) {
$price = ...
}Le code devient rapidement difficile à comprendre, à maintenir et à faire évoluer.
Ce problème n’est pas technique.
C’est un problème de modélisation métier.
La solution de cette complexité métier
La vraie solution consiste à rendre le métier explicite.
class Discount {
public function __construct(
public float $value,
public ?float $cap = null
) {}
}class LoyaltyDiscountRule implements PricingRule {
public function apply(Context $ctx) {
if (!$ctx->user->isLoyal()) return;
$ctx->addDiscount(new Discount(0.10));
}
}class AggressiveMarketRule implements PricingRule {
public function apply(Context $ctx) {
if ($ctx->market !== ’aggressive’) return;
$ctx->modifyDiscount(function (Discount $d) use ($ctx) {
if ($ctx->user->country !== ’DE’) {
$d->cap = 0.05;
}
});
}
}On passe d’un code impératif à un modèle métier explicite et composable.
C’est cela qui apporte de la clarté et de la robustesse.
Un bon modèle ne suffit pas
Sous pression, des raccourcis apparaissent :
if ($campaign) {
return 9.99;
}Ou pire, une dépendance vers l’extérieur :
class LoyaltyDiscountRule {
public function __construct(private RequestStack $request) {}
}Le problème devient alors :
Comment empêcher le modèle d’être contourné ?
Apparition de la Clean Architecture
La Clean Architecture propose une réponse simple :
Le métier ne doit dépendre de rien d’extérieur.
C’est précisément ce que les exemples précédents violent : un if ($campaign) introduit une logique externe dans le domaine, un RequestStack injecté crée une dépendance vers le framework. La Clean Architecture interdit structurellement ces contournements en séparant le système en couches :
- Domaine (logique métier pure) — c’est ce qu’on protège. Il ne connaît ni le framework, ni la base de données, ni HTTP.
- Application (cas d’usage) — coordonne les objets du domaine pour réaliser un cas d’usage. Elle dit quoi faire et dans quel ordre, sans contenir de logique métier ni de détails techniques. Si on retire le framework, le Use Case doit encore avoir du sens.
- Infrastructure (technique) — dépend du domaine, jamais l’inverse. Les détails techniques s’adaptent au métier, pas le contraire.
Cette règle de dépendance unidirectionnelle est le cœur du dispositif : l’infrastructure peut changer, le domaine reste intact.
Son objectif n’est pas de créer un bon modèle.
Son objectif est de protéger ce modèle.
Ce que la Clean Architecture n’est pas
La Clean Architecture ne garantit pas :
- une bonne modélisation métier
- un code propre
- un respect des couches
- des tests automatiquement corrects
Un projet peut être en Clean Architecture et être mal conçu.
Le problème réel d’une architecture : l’enforcement
Sans contraintes vérifiées mécaniquement, une architecture n’est qu’une convention — et les conventions sont facilement ignorées. L’enforcement, c’est précisément ce qui transforme une intention architecturale en règle réellement respectée.
La dégradation est progressive et silencieuse
Aucune violation ne semble grave sur le moment. Un RequestStack injecté dans un service domaine “juste pour ce cas”. Une règle métier glissée dans un contrôleur “exceptionnellement”. Un raccourci pris un vendredi soir sous pression de livraison. Chaque décision isolée paraît raisonnable. C’est leur accumulation qui tue l’architecture — et personne ne s’en rend compte avant que le coût soit devenu irréversible.
Toutes les violations ne sont pas délibérées
Certaines sont conscientes : un développeur qui sait qu’il contourne une règle mais choisit d’aller vite. D’autres sont involontaires : un développeur qui ne connaît pas suffisamment l’architecture et place du code au mauvais endroit sans le savoir. Les deux sont dangereuses, mais pour des raisons différentes. Les premières révèlent un problème de discipline, les secondes un problème de transmission.
L’enforcement n’est pas de la bonne volonté
Compter sur le fait que chaque développeur respectera les règles par conviction est insuffisant. L’architecture doit être vérifiée mécaniquement — en CI, dans les tests, dans les outils d’analyse statique. Une règle qui ne peut pas être contrôlée automatiquement finira par être ignorée, même dans les meilleures équipes.
Sans enforcement, l’illusion est pire que l’absence d’architecture
Un projet sans règle sait qu’il accumule de la dette. Un projet qui se croit en Clean Architecture mais dont les couches sont violées en permanence a un problème supplémentaire : la fausse confiance. On croit que le système est protégé alors qu’il ne l’est plus. C’est cette illusion qui rend la situation particulièrement difficile à diagnostiquer et à corriger.
La question n’est donc pas “avons-nous une architecture ?” mais “avons-nous les moyens de la faire respecter ?”
Ce qui compte vraiment
La répartition des rôles est claire : la modélisation métier est fondamentale, l’architecture organise et protège, les outils (frameworks, injection de dépendances) ne viennent qu’en dernier.
On a tendance à inverser cet ordre. On choisit le framework avant de comprendre le domaine, on débat d’architectures avant d’avoir modélisé une seule règle métier. Résultat : on bétonne les fondations d’une maison pour un château de cartes.
Les outils servent l’architecture. L’architecture sert le métier. Jamais l’inverse.
Conclusion
La Clean Architecture n’est pas née d’une obsession pour les couches ou les interfaces. Elle est née d’un problème concret : comment empêcher la logique métier d’être contaminée, contournée, noyée sous les détails techniques ?
Sa réponse est structurelle : rendre la dépendance vers le métier obligatoire, et la dépendance vers l’infrastructure impossible depuis le domaine.
Mais cette protection n’a de valeur que si le modèle qu’elle protège reflète réellement le métier. Une Clean Architecture sur un domaine mal modélisé, c’est une forteresse construite autour d’un trône vide.
Commencez par comprendre votre métier. Modélisez-le explicitement. Alors seulement, l’architecture a quelque chose à protéger.