Bibliothèque · Résumé et avis

Clean Architecture

De Robert C. Martin. Le livre derrière hexagonale, onion et clean : une règle sur la direction de vos dépendances, et tout le reste est un détail.

FR EN
Couverture de Clean Architecture, Robert C. Martin

Clean Architecture

Clean Architecture: A Craftsman's Guide to Software Structure and Design

7.2 /10

« Verbeux, prêcheur, à moitié autobiographique : et pourtant la Dependency Rule vaut le livre entier. »

  • AuteurRobert C. Martin · Uncle Bob
  • VOPrentice Hall, 2017 · 432 pages
  • ÉditionÉdition unique (2017), en anglais
  • Fiche~18 min de lecture
Notation du livre sur 5 dimensionsIdées9/10Applicable7/10Lisibilité7/10Actualité8/10Exemples5/10

Une seule règle de dépendance, et la base de données redevient un détail : le plan du bâtiment pour votre code.

Pourquoi ce livre

Clean Code regarde la ligne et la fonction ; Clean Architecture monte d'un étage et regarde le plan du bâtiment : qui a le droit de dépendre de qui. Même auteur, même série, la suite logique. Ma fiche Clean Code y renvoyait déjà.

C'est aussi le livre qui a cristallisé toute une famille d'architectures (hexagonale, onion, BCE) en un diagramme et une règle. Que vous adoriez ou combattiez les quatre cercles concentriques, ils viennent d'ici.

Les idées qui restent

Trente-quatre chapitres courts, une seule thèse. Voilà ce qui reste vraiment.

1La spirale du code de plus en plus cher

Tout projet démarre vite, puis chaque fonctionnalité coûte un peu plus que la précédente, jusqu'à l'enlisement. Martin ouvre le livre avec les courbes d'une vraie entreprise (anonymisée) sur huit versions :

  • le coût par ligne de code de la version 8 est 40 fois celui de la version 1 ;
  • la masse salariale mensuelle atteint 20 millions de dollars... et n'achète presque plus rien ;
  • l'effectif explose pendant que la productivité par développeur rampe vers zéro.

Le mensonge que tout le monde se raconte, cité tel quel : « On nettoiera plus tard ; il faut d'abord arriver sur le marché ! » (ch. 1). Sauf que ce « plus tard » n'arrive jamais : une fois sur le marché, il y a une prochaine échéance, un concurrent à rattraper, une fonctionnalité réclamée par les clients. La pression qui a justifié de salir le code hier justifie de ne pas le nettoyer aujourd'hui, et ainsi de suite jusqu'à l'enlisement. D'où la définition sur laquelle Martin construit le livre : « Le but de l'architecture logicielle est de minimiser les ressources humaines nécessaires pour construire et maintenir le système demandé » (ch. 1). Pas l'élégance, pas les diagrammes : la facture.

Le chapitre 2 nomme l'arbitrage : un logiciel a deux valeurs, le comportement (urgent) et la structure (important), et les équipes promeuvent en boucle l'urgent au-dessus de l'important. Exactement à l'envers, dit Martin.

2Trois paradigmes, trois interdictions

Les trois paradigmes de programmation ont tous été découverts entre 1958 et 1968. Aucun depuis. Et Martin les définit à rebours de la brochure habituelle : chacun retire un pouvoir au programmeur, aucun n'en ajoute.

  • Le structuré (Dijkstra, 1968) retire le goto, l'instruction qui sautait n'importe où dans le programme. Sans lui, le code se lit de haut en bas : vos if, while et for sont ce qui reste quand on a enlevé le saut sauvage ;
  • L'objet (Dahl et Nygaard, 1966) retire les sauts indirects sauvages : on n'appelle plus « le code dont l'adresse traîne quelque part », on appelle une méthode, et le langage garantit qu'elle existe. C'est le polymorphisme apprivoisé ;
  • Le fonctionnel (Church, 1936) retire l'affectation : une valeur créée ne change plus jamais. Et si rien ne change, des familles entières de bugs (état partagé, concurrence) disparaissent avec.

« Chacun des paradigmes retire des capacités au programmeur. Aucun ne lui en ajoute de nouvelles » (ch. 3). Que reste-t-il à retirer ? Rien, parie Martin : il n'y aura pas de quatrième paradigme. La leçon pratique : un paradigme est une contrainte qu'on accepte parce qu'elle rend le code prévisible, pas un gadget de plus.

Le pari tient-il en 2026 ?

À moitié. Depuis le livre, au moins deux idées ont suivi exactement le même schéma « on retire pour rendre prévisible » :

Rust et l'ownership : on retire le droit d'avoir deux endroits du code qui modifient la même donnée en même temps. Le compilateur refuse le programme, et toute une famille de bugs de concurrence disparaît.

La concurrence structurée : on retire le droit de lancer une tâche de fond qui survit au bloc qui l'a créée. Un essai célèbre de 2018 s'appelle d'ailleurs « Go statement considered harmful », calqué sur l'article anti-goto de Dijkstra : le spawn sauvage est le goto de la concurrence.

Martin parlait du code séquentiel, et là son inventaire est sans doute complet. Mais sa mécanique du progrès (retirer, pas ajouter) continue de produire : raison sur le principe, tort sur la prophétie.

3Le SRP n'est pas ce que vous croyez

Deux sigles à poser d'abord. SOLID, c'est l'acronyme des cinq principes de conception objet popularisés par Martin lui-même : Single responsibility, Open/closed, Liskov substitution, Interface segregation, Dependency inversion. Le SRP (Single Responsibility Principle, principe de responsabilité unique) est le premier des cinq, le plus cité, et le plus déformé.

Martin le dit lui-même : « une fonction ne fait qu'une seule chose » est un autre principe, plus bas niveau, et ce n'est PAS le SRP. La vraie définition : « Un module ne doit être responsable que devant un seul et unique acteur » (ch. 7). Un acteur : un groupe de personnes qui demandent le même genre de changements.

L'exemple du livre : une classe Employee avec trois méthodes.

  • calculatePay() répond à la direction financière ;
  • reportHours() répond à la direction des opérations ;
  • save() répond aux DBA.

Trois acteurs dans la même classe. Le jour où la finance fait modifier un calcul d'heures partagé, les rapports des opérations deviennent silencieusement faux ; le livre met en scène un COO furieux et des millions perdus à cause des données erronées (ch. 7). Découper par acteur, c'est découpler les colères.

Le mauvais et le bon découpage, côte à côte :

// ✗ AVANT : un seul module, trois patrons : leurs demandes se marchent dessus
class Employee {
  name
  hourlyRate       // taux horaire
  hoursWorked      // heures pointées

  calculatePay()   // la finance
  reportHours()    // les opérations
  save()           // les DBA

  regularHours()   // privée, partagée par les deux premières : la bombe du ch. 7
}

// ✓ APRÈS : un module par patron, les données partagées à part (ch. 7)

// les données seules, sans aucune logique : juste la fiche de l'employé
class EmployeeData {
  name
  hourlyRate     // taux horaire
  hoursWorked    // heures pointées
}

class PayCalculator { calculatePay(EmployeeData d) }   // la finance
class HourReporter  { reportHours(EmployeeData d) }    // les opérations
class EmployeeSaver { save(EmployeeData d) }           // les DBA

Regardez bien ce qui a bougé entre l'avant et l'après : pas les données, la logique. La fiche de l'employé (nom, taux horaire, heures) reste entière dans EmployeeData, une structure passive que les trois modules lisent chacun de leur côté. Ce sont les trois méthodes, c'est-à-dire les trois raisons de changer, qui ont chacune déménagé chez leur patron. La demande de la finance ne touche plus que PayCalculator : les rapports des opérations ne peuvent plus casser en silence, le code qui les produit n'a pas bougé. Et regularHours(), le calcul partagé ? Chaque module garde sa propre version. Martin assume la duplication : deux calculs qui se ressemblent aujourd'hui mais changeront pour des raisons différentes demain ne sont pas une vraie duplication. Le critère de découpage n'est donc pas « qu'est-ce qui fait quoi » mais « qui demandera de le changer ».

Et la composition dans tout ça ?

Presque, mais pas encore. PayCalculator reçoit EmployeeData en paramètre, s'en sert le temps d'un calcul, et la rend : c'est une simple dépendance d'usage, le lien le plus faible entre deux classes. La composition, c'est le cran au-dessus : un objet qui en contient durablement un autre comme pièce détachée. Elle arrive dans la suite de l'exemple du livre : une façade EmployeeFacade qui contient les trois modules et délègue, pour garder un point d'entrée unique.

Le geste de fond, lui, est bien le même que le « préférez la composition à l'héritage » des Design Patterns : remplacer la grosse classe qui fait tout par de petites pièces dédiées qu'on assemble. Le SRP dit où couper (une pièce par donneur d'ordres), la composition dit comment remonter les pièces ensemble.

4Le vrai superpouvoir de l'objet : retourner les flèches

Martin démonte la définition classique de l'objet. L'encapsulation ? Le C la faisait parfaitement avec les fichiers .h/.c, et C++ l'a abîmée en exposant les membres privés dans les en-têtes. L'héritage ? Une astuce de structs que le C simulait déjà à la main. Ce qui reste : « l'objet, c'est la capacité, grâce au polymorphisme, d'obtenir un contrôle absolu sur chaque dépendance de code source du système » (ch. 5).

Concrètement : sans interface, le code métier appelle la base de données, donc il dépend d'elle ; l'import suit l'appel. Avec une interface, le code métier déclare « il me faut quelque chose qui sache sauvegarder », et c'est la base de données qui implémente. À l'exécution, l'appel va toujours du métier vers la base, mais la dépendance de code source pointe maintenant de la base vers le métier. La flèche s'est retournée. La conséquence est énorme : l'interface utilisateur et la base de données deviennent des plugins des règles métier, remplaçables comme on change d'imprimante.

Mais alors, à quoi sert l'objet, si c'est l'interface qui fait le travail ?

C'est exactement la réponse du chapitre 5. On n'a pas besoin d'objet pour retourner la flèche : les programmeurs C le faisaient déjà avec des pointeurs de fonction (« tel trou sera rempli par telle fonction, branchée à la main au démarrage »). Mais c'était artisanal et dangereux : rien ne vérifiait que le trou était rempli, ni avec une fonction de la bonne forme. Un oubli, et le programme sautait à une adresse pourrie en pleine exécution.

L'apport de l'objet tient en une ligne : rendre ce retournement sûr, banal et vérifié par le compilateur. Une interface est un pointeur de fonction apprivoisé : l'implémentation existe, les signatures collent, le compilateur le garantit avant l'exécution. Ce qui exigeait une discipline héroïque en C devient un outil du quotidien. L'objet n'a rien inventé ; il a rendu l'inversion praticable à l'échelle d'un système entier. Et ça boucle avec l'idée 2 : retirer les pointeurs de fonction sauvages, c'est précisément ce que l'objet retire.

La preuve par Go, qui n'a ni classes ni héritage et retourne la flèche mieux que personne : tout type qui possède les bonnes méthodes satisfait l'interface, automatiquement, sans la déclarer. Le métier définit son interface chez lui, et le package base de données ne sait même pas qu'elle existe. Go a jeté l'emballage de l'objet et gardé le seul morceau qui comptait selon Martin : l'appel indirect dont le compilateur garantit la cible.

5Un bon architecte maximise les décisions non prises

La définition du livre : l'architecture est la forme donnée au système pour en faciliter le développement, le déploiement, l'exploitation et la maintenance ; et la stratégie, c'est « laisser le plus d'options ouvertes possible, le plus longtemps possible » (ch. 15). D'où la phrase la plus célèbre du livre : « Un bon architecte maximise le nombre de décisions non prises » (ch. 15).

La preuve vécue : FitNesse, le wiki de tests que Martin construit avec son fils en 2001. Plutôt que de choisir une base de données au départ, ils écrivent une interface WikiPage et stockent les pages en RAM, puis dans des fichiers plats. Résultat : « pendant 18 mois, nous n'avons eu aucun problème de schéma, de requêtes, de serveur de base de données, de mots de passe, de temps de connexion » (ch. 17). La chute : le support MySQL a fini par être écrit... par un client, en une journée, parce que la frontière était propre. Personne d'autre ne l'a jamais utilisé. L'option a été supprimée. La décision repoussée était devenue inutile.

Un serveur de base de données avec un chapeau de représentant de commerce et une mallette attend sur le paillasson devant une porte vitrée, pendant que deux développeurs codent tranquillement à l'intérieur
FitNesse a laissé la base de données patienter 18 mois sur le paillasson. Elle n'est jamais vraiment entrée.

6Quatre cercles, une seule règle

Le diagramme aux cercles concentriques est devenu l'image la plus connue du livre. Martin ne l'a pas inventé de zéro : c'est la synthèse d'architectures cousines qui disaient déjà la même chose. L'architecture hexagonale d'Alistair Cockburn (2005, aussi appelée « ports & adapters ») : le cœur de l'application expose des prises standardisées, et chaque technologie vient s'y brancher comme un appareil sur une multiprise. Le BCE d'Ivar Jacobson (1992, pour Boundary-Control-Entity, frontière-contrôle-entité) : découper chaque fonctionnalité en trois rôles, ce qui parle au monde extérieur, ce qui orchestre, ce qui porte les données métier. Mêmes intuitions, dessins différents ; Martin les fond en quatre couches, de l'intérieur vers l'extérieur.

Prenons un site de location de voitures pour rendre chaque couche concrète :

  • Entités : les règles métier qui existeraient même sans informatique. « Un conducteur doit avoir le permis depuis 2 ans », « une caution est exigée au-delà de tel prix ». Le gérant de l'agence les appliquait déjà avec un carnet papier ;
  • Cas d'usage : les règles propres à cette application. « Réserver un véhicule » = vérifier la disponibilité, calculer le prix, bloquer le créneau, déclencher l'email. C'est le scénario, étape par étape, sans rien savoir de l'écran ni de la base ;
  • Adaptateurs d'interface : les traducteurs entre le dedans et le dehors. Le contrôleur qui transforme la requête HTTP en appel au cas d'usage, le repository qui transforme « bloquer le créneau » en requête SQL. Tout le SQL du projet est confiné ici ;
  • Frameworks et drivers : Symfony, MySQL, le navigateur. De la technologie interchangeable, surtout de la colle.

Et une seule loi, la Dependency Rule : « les dépendances de code source ne doivent pointer que vers l'intérieur, vers les politiques de plus haut niveau » (ch. 22). Traduction concrète : un fichier a le droit d'importer des fichiers de son cercle ou des cercles plus intérieurs, jamais l'inverse. Le contrôleur (adaptateur) peut importer le cas d'usage « Réserver un véhicule » ; le cas d'usage peut importer l'entité Conducteur ; mais l'entité Conducteur, elle, n'importe rien qui vienne de l'extérieur. Et « ne rien savoir » s'entend au sens strict : pas un import, pas un nom de classe, pas même le mot « MySQL » quelque part dans le fichier.

Le test tient en une ligne : ouvrez une de vos entités et lisez ses use en tête de fichier. Si vous y voyez Symfony, Doctrine ou Request, la règle est violée : votre règle métier est attachée à une technologie, et elle tombera avec elle. Aucun import de framework dans vos entités. Jamais.

Mais mes entités Symfony SONT des entités Doctrine !

Collision de vocabulaire : même mot, deux concepts. Une entité Doctrine est un modèle de persistance (colonnes, jointures) ; dans les cercles de Martin, elle vit chez les adaptateurs. make:entity a juste installé l'idée que c'était le cœur du projet. La version puriste sépare les deux, exemple avec le User qu'on a tous :

// 1. Domaine : PHP pur, zéro use framework. Les règles vivent ici.
final class User {
  public function suspend(): void {
    if ($this->hasActiveSubscription()) {
      throw new CannotSuspendPayingUser();   // règle métier
    }
    $this->status = Status::Suspended;
  }
}

// 2. Infrastructure : les use Doctrine vivent ICI
#[ORM\Entity]
class DoctrineUser { /* id, colonnes, jointures */ }

class DoctrineUserRepository implements UserRepository {
  public function save(User $u): void { /* traduit User → DoctrineUser */ }
}

// 3. Sécurité : l'UserInterface de Symfony aussi est un adaptateur
class SecurityUser implements UserInterface { /* enveloppe User */ }

Le prix est réel : trois classes et un traducteur là où make:entity en faisait une. Quand le payer : quand votre User porte de vraies règles (cycle de vie invité → vérifié → suspendu, droits, quotas, facturation) que vous voulez tester sans démarrer une base. Quand s'en passer : quand User n'est qu'un email, un mot de passe et des rôles ; là, la version puriste est de la cérémonie pure, gardez une seule classe et assumez l'entorse. Le signal pratique : le jour où un test unitaire de règle métier vous force à charger Doctrine, c'est le moment de séparer.

Le test du chapitre 21, la revue d'architecture la plus rapide du monde : ouvrez le dossier racine de votre projet. Crie-t-il « comptabilité »... ou crie-t-il « Rails » ? Une architecture devrait dire ce que le système FAIT, pas avec quoi il est construit.

7Le problème des chatons (vos microservices sont couplés)

2017 : tout le monde découpe tout en microservices, et l'argument de vente est toujours le même : des services indépendants, déployables séparément, donc découplés. Martin pose la question qui fâche : découplés par rapport à quel changement ? C'est le seul test qui compte.

Son contre-exemple : un agrégateur de taxis genre Uber, découpé proprement en quatre services : l'interface client, la recherche de chauffeur, la sélection du véhicule, le dispatch. Sur le papier, chacun vit sa vie. Puis le marketing annonce un nouveau produit : la livraison de chatons à domicile. Déroulez ce que ça implique : les allergies des clients (interface), les allergies des chauffeurs (recherche), les critères de véhicule adapté aux animaux (sélection), les règles de livraison (dispatch). Les quatre services doivent changer ensemble et être redéployés de façon coordonnée. Face à ce changement-là, le découpage n'a rien découplé du tout : « Les services qui se contentent de séparer des comportements applicatifs ne sont guère plus que des appels de fonction coûteux » (ch. 27). Coûteux, parce qu'on a remplacé un appel de fonction par un appel réseau : plus lent, et qui peut tomber en panne.

La leçon n'est pas anti-services, elle est anti-réflexe :

  • un service n'est une vraie frontière que si les changements probables restent dedans. Le test pratique : prenez la prochaine demande du marketing et comptez combien de services elle traverse ;
  • les frontières qui protègent vraiment sont celles des quatre cercles (idée 6) : métier, cas d'usage, adaptateurs. Et elles doivent exister à l'intérieur de chaque service aussi : un bon service est un petit monolithe propre, pas un gros fichier derrière une API ;
  • une bonne architecture permet de naître monolithe, grandir en unités déployables, puis en services si le besoin arrive un jour (ch. 16). Le découpage réseau est une option qu'on garde ouverte, pas un point de départ ;
  • et la pique, en note de bas de page : « le nombre de micro-services sera à peu près égal au nombre de programmeurs » (ch. 27). Comprendre : on découpe trop souvent pour refléter l'organigramme (une équipe, un service), pas la structure du problème.
Un livreur dans une petite voiture débordante de chatons arrive devant un immeuble, pendant que derrière lui cinq petits bâtiments identiques reliés par des câbles emmêlés clignotent tous en alarme rouge
Un seul nouveau produit, les chatons. Et tous les services « indépendants » tombent en panne ensemble.

8Tout est détail, et la discipline ne vous sauvera pas

La fin du livre enfonce trois clous avec le même marteau :

  • la base de données est un détail : une technologie de disque, pas le centre de votre système ;
  • le web est un détail : « le GUI est un détail. Le web est un GUI. Donc le web est un détail » (ch. 31). L'industrie oscille entre client lourd et serveur lourd depuis les années 1960 ; votre cœur métier ne devrait pas suivre le pendule ;
  • le framework est un mariage asymétrique : vous vous engagez pour la vie, son auteur ne s'engage à rien. « N'épousez pas le framework ! » (ch. 32) : utilisez Spring, mais pas de @Autowired dans vos objets métier.
« La base est un détail » : et si tout mon projet est centré sur un pattern data ?

L'objection fait mal, et Martin y répond à moitié. Sa distinction réelle : le SGBD est un détail, le modèle de données ne l'est pas. L'event sourcing, par exemple, passe son test : « notre source de vérité, c'est l'historique des faits, pas l'état courant » est une décision métier, une politique de haut niveau (et le chapitre 6 en fait même l'éloge). Ce qui reste un détail, c'est l'event store : EventStoreDB, Kafka ou une table Postgres append-only, vos cas d'usage n'ont pas à le savoir.

La règle a quand même une limite. Avec certaines bases, on ne choisit pas qu'une technologie, on choisit une façon de penser. Exemple : DynamoDB (la base NoSQL d'Amazon) n'est rapide que si vous rangez vos données en fonction des questions que vous poserez. Tout le plan des données est construit autour de ces questions. Un projet conçu comme ça ne « changera pas de base » en remplaçant une classe derrière une interface : il faudrait repenser le rangement entier. La classe est remplaçable, la façon de penser ne l'est pas.

D'où la version honnête de la règle : vous ne changerez probablement jamais de base, et ce n'est pas grave, ça n'a jamais été son vrai bénéfice. Le vrai bénéfice, c'est de pouvoir tester vos règles métier sans démarrer MySQL, et de garder un code métier lisible sans connaître Doctrine. Le grand choix de données (relationnel, événements, graphe), on l'assume comme une décision d'architecture. La marque de la base, elle, reste un détail.

Puis le chapitre 34, écrit par un invité (Simon Brown), termine le livre sur une douche froide. Son constat : vous pouvez dessiner les plus beaux cercles du monde, si chaque classe du projet est public, n'importe quel développeur pressé peut court-circuiter le plan. Exemple : le contrôleur est censé passer par le cas d'usage « Réserver », qui applique les règles. Mais rien n'empêche d'écrire dans le contrôleur un appel direct au repository, qui saute les règles. Ça compile, ça marche, ça part en prod. L'architecture n'existait que sur le dessin, et dans la bonne volonté de chacun.

Sa réponse : demander au compilateur de monter la garde. En Java, une classe déclarée sans le mot public n'est visible que dans son propre dossier. Déclarez le repository comme ça, et le contrôleur ne peut plus l'appeler directement : le raccourci interdit ne compile pas, au lieu d'être un oubli à attraper en revue de code. « Le diable est dans les détails d'implémentation » (ch. 34). En PHP, pas d'équivalent natif ; on s'en approche avec un outil comme Deptrac, qui fait échouer la CI quand une couche importe ce qu'elle ne devrait pas.

Trois choses que je ne savais pas

Mon avis, honnêtement

J'ai lu ce livre comme on écoute un vieux prof qui se répète un peu mais qui a tout vu. Martin code depuis 1964, et sa grande idée tient sur un post-it : les dépendances pointent vers l'intérieur. Le reste du livre, c'est cette phrase, racontée avec des anecdotes. Mais quelle phrase : chaque framework JavaScript mort depuis 2017 plaide pour elle, et mon propre historique de projets est un petit cimetière de codes mariés à leur framework.

La critique méritée : c'est verbeux, prêcheur, et radin en exemples. Le grand cas d'école est Hunt the Wumpus, un jeu textuel de 1972, et le seul chapitre avec du code moderne réaliste a été écrit par un invité (Simon Brown). Pire : le diagramme aux quatre cercles est devenu une religion. J'ai vu des CRUD de trois écrans avec douze fichiers pour lire une table. Appliquer Clean Architecture partout, c'est rater le livre, qui dit littéralement que l'architecture sert à économiser de l'effort.

Mon conseil de lecture, concrètement : le livre fait 400 pages, mais l'essentiel tient dans une centaine, celles de la Dependency Rule, de l'histoire de FitNesse et du problème des chatons. Cette centaine-là, je la recommande à presque tout dev qui a quelques années de code derrière lui. Le reste (les leçons d'histoire, les chapitres très Java), survole-le sans culpabiliser, je ne le dirai à personne.

Odilon

Toujours valable en 2026 ?

Plus qu'en 2017, pour une raison que Martin ne pouvait pas prévoir : l'IA écrit une part croissante du code, mais elle ne décide pas où va le code. Un projet où le SQL vit dans un seul anneau et les règles métier dans un autre, c'est aussi un projet qu'un agent IA peut modifier sans tout casser : les frontières que Martin a tracées pour les humains servent maintenant deux fois. Ce qui a vieilli : les réflexes très centrés Java, les longs détours par le matériel des années 1960, et l'hypothèse qu'on contrôle toutes ses dépendances (l'ère npm et ses chaînes d'approvisionnement dit le contraire).

Pour qui ?

Lisez-le si

  • Vous avez 3 ans de code ou plus et vos projets ralentissent version après version
  • Tout le monde crie « microservices » et il vous faut des arguments pour démarrer monolithe propre
  • Vous voulez savoir d'où sortent vraiment hexagonale, onion et clean
  • Vous avez aimé Clean Code et voulez l'étage au-dessus : la structure plutôt que les lignes

Passez votre chemin si

  • Vous attendez un tutoriel avec du code : il n'y en a presque pas
  • Vous débutez : lisez Clean Code d'abord, celui-ci suppose des cicatrices
  • Les histoires de PDP-8 et de cartes perforées vous endorment

Pour aller plus loin

La direction des dépendances se pratique dans mon cours POO (interfaces, composition, injection). Côté bibliothèque, Clean Code est le même auteur un étage plus bas, A Philosophy of Software Design est la contre-voix calme (la profondeur plutôt que les règles), The Pragmatic Programmer partage la guerre contre le couplage, et Team Topologies reprend la loi de Conway là où le chapitre 16 la laisse.

Commentaires (0)

Voir toute la bibliothèque

D'autres fiches arrivent : un livre à la fois, la substantifique moelle seulement.