26 mai 2026 · Flutter · Architecture
Clean Architecture en Flutter : pourquoi je l'impose sur mes projets au long cours
Structure core/features, séparation data/domain/presentation : ce que la Clean Architecture coûte au démarrage et ce qu'elle rapporte sur la durée.
Sur un petit projet Flutter, tout mettre dans lib/ avec quelques dossiers
screens/ et widgets/ fonctionne très bien. Puis le projet grandit, un
deuxième contributeur arrive (ou vous-même, six mois plus tard), et chaque
modification devient une expédition. La Clean Architecture est la réponse
que j'ai adoptée pour tout projet destiné à vivre plus d'un an ; elle se
paie dès les premières semaines.
La structure
Le principe : séparer ce que fait l'application (le domaine) de comment elle le fait (les détails techniques). Concrètement :
lib/
├── core/ # transversal : erreurs, réseau, DI, thème
└── features/
└── auth/
├── data/ # sources (API, base locale), repositories impl
├── domain/ # entités, interfaces de repositories, use cases
└── presentation/ # blocs/cubits, écrans, widgets
La règle de dépendance est la seule chose à retenir : les flèches
pointent vers le domaine. La couche presentation ne connaît que
domain ; data implémente les interfaces définies par domain ; domain
ne connaît personne. Votre logique métier ne sait pas si les données
viennent d'une API REST, d'une base SQLite ou d'un mock de test.
Ce que ça rapporte concrètement
La testabilité d'abord. Un use case qui dépend d'une interface de repository se teste avec un mock en trois lignes, sans réseau, sans base, sans widget. C'est ce qui rend possible une vraie couverture de tests sur la logique métier, celle qui coûte cher quand elle casse.
Le remplacement des détails ensuite. Changer de solution de stockage
local, remplacer un endpoint, passer d'un backend à un autre : si la
frontière data/domain est propre, c'est un chantier localisé dans data/,
pas une réécriture.
L'onboarding enfin. Sur une feature inconnue, on sait toujours où regarder : le use case dit ce que fait la feature, le bloc dit comment l'écran réagit, le repository dit d'où viennent les données. La structure est la documentation.
Ce que ça coûte, soyons honnêtes
Plus de fichiers, plus d'indirection, et une cérémonie qui peut sembler absurde sur un CRUD simple (une entité, un modèle, un mapper, une interface, une implémentation... pour un écran de liste). Deux garde-fous :
- Ne créez un use case que quand il y a de la logique. Pour un simple passage de plat, le bloc peut appeler le repository directement : la pureté dogmatique est l'ennemie de l'adoption.
- La structure par feature est plus importante que le nombre de
couches. Si vous ne retenez qu'une chose : isolez chaque feature dans
son dossier avec ses trois couches, plutôt que des couches globales
(
models/,services/) qui mélangent toutes les features.
La leçon
La Clean Architecture n'est pas un badge de sérieux, c'est un pari sur la durée : vous acceptez d'écrire un peu plus aujourd'hui pour que le projet reste modifiable dans deux ans. Sur un prototype jetable, c'est du sur-coût. Sur un produit au long cours (celui qu'on maintient seul le soir, celui qui doit survivre à ses propres pivots), c'est ce qui fait la différence entre itérer et réécrire.