Vol. 0 · № 02 · Un atelier d'architectureAn architecture workshop

Le coût caché de l'indirectionThe hidden cost of indirection

Le contre-poids du numéro précédent. Chaque couche ajoute un saut : un nom à apprendre, un fichier à ouvrir, un cadre de pile à traverser. Elle ne vaut son loyer que si elle décide quelque chose.The counterweight to the previous issue. Every layer adds a hop: a name to learn, a file to open, a stack frame to step through. It only earns its rent if it decides something.

AudienceAudience
Dev à l'aise en code, qui veut raisonner architectureDev fluent in code, ready to reason about architecture
Format
Self-paced
ChapitresChapters
5
Date
Juin 2026June 2026
≈ 18 min●○○○MéthodeIndirectionTradeoff
SommaireContents ·
№ 01CadrageFraming3 min

Chaque abstraction ajoute un saut. La question : paie-t-elle son loyer ?Every abstraction adds a hop. The question: does it pay its rent?

Le numéro précédent disait : isole l'axe qui change. Voici le contre-poids. Une couture n'est jamais gratuite — elle ajoute un nom à apprendre, un fichier à ouvrir, un cadre de pile à traverser au débogueur, parfois un aller-retour réseau. L'indirection est l'outil principal de l'architecte… et son vice principal. Suis un simple « récupère l'email de l'utilisateur 42 » à travers ses couches.The previous issue said: isolate the axis that changes. Here's the counterweight. A seam is never free — it adds a name to learn, a file to open, a stack frame to step through in the debugger, sometimes a network round-trip. Indirection is the architect's main tool… and main vice. Follow a plain 'fetch user 42's email' down through its layers.

La pile d'appels — qui transforme, qui ne fait que transmettre ?The call stack — who transforms, who merely forwards?
Controller
getUserEmail(42)
passe-platpass-through
↓
Service
getUserEmail(42)
passe-platpass-through
↓
Manager
getUserEmail(42)
passe-platpass-through
↓
Repository
SELECT email … → User
transformetransforms
Le réflexe du numéroThe issue's reflex

Trois couches sur quatre transmettent l'appel sans rien décider. Une seule transforme — le Repository, qui convertit du SQL en objet métier. Le réflexe : pour chaque couche traversée, « que décide-t-elle ? ». Si la réponse est « rien, elle redélègue », le saut ne paie pas son loyer.Three layers out of four forward the call without deciding anything. Only one transforms — the Repository, turning SQL into a business object. The reflex: for each layer crossed, 'what does it decide?'. If the answer is 'nothing, it re-delegates', the hop isn't paying its rent.

Pourquoi ce numéro suit le premier.Why this issue follows the first.

Vol 0 #1 apprend à poser des coutures ; appliqué sans frein, ce réflexe produit des « lasagnes » de couches vides. Ce numéro est le garde-fou : toute isolation a un loyer, et une abstraction qui ne protège aucun axe réel est une dette, pas un actif.Vol 0 #1 teaches you to place seams; applied without a brake, that reflex breeds 'lasagnas' of empty layers. This issue is the guardrail: every isolation has rent, and an abstraction guarding no real axis is debt, not an asset.

№ 02La douleurThe pain4 min

Le loyer se paie en lecture : huit cadres de pile pour un getter.The rent is paid in reading: eight stack frames for a getter.

L'indirection ne coûte presque rien à l'écriture — c'est ça le piège. Le coût arrive plus tard, et il tombe sur quelqu'un d'autre : celui qui débogue. Pour comprendre d'où vient un email mal formaté, il ouvre le Controller, qui renvoie au Service, qui renvoie au Manager, qui renvoie au Repository. Quatre fichiers, quatre sauts, et la seule ligne qui compte était tout en bas.Indirection costs almost nothing to write — that's the trap. The cost comes later, and it lands on someone else: whoever debugs. To understand where a malformed email comes from, they open the Controller, which points to the Service, which points to the Manager, which points to the Repository. Four files, four hops, and the only line that mattered was at the very bottom.

La trace : huit cadres, une seule décisionThe trace: eight frames, one decision
UserController.get_email(42)      → délègue
  UserService.get_email(42)       → délègue
    UserManager.get_email(42)     → délègue
      UserRepository.find(42)     → SQL + mapping   ← la seule ligne utile
      ↑ remonte le résultat, inchangé
    ↑ remonte le résultat, inchangé
  ↑ remonte le résultat, inchangé
↑ remonte le résultat, inchangé
Ce que ça coûteWhat it costs

Trois couches qui ne font que transmettre, ce sont trois fichiers à ouvrir, trois noms à retenir, trois cadres de pile à sauter — pour zéro décision. Le débogueur traverse de la plomberie. Et le jour où la signature change, il faut la modifier en quatre endroits identiques.Three layers that only forward are three files to open, three names to remember, three stack frames to step over — for zero decisions. The debugger wades through plumbing. And the day the signature changes, you edit it in four identical places.

Le diagnostic.The diagnosis.

Ce n'est pas un problème de qualité : chaque couche est propre. C'est un problème de loyer. Une abstraction se paie en charge cognitive, en latence parfois, en sauts de pile toujours. Elle ne vaut son prix que si elle achète une liberté — une décision, une transformation, une frontière. Sinon, c'est une taxe pure.It's not a quality problem: each layer is clean. It's a rent problem. An abstraction is paid in cognitive load, sometimes latency, always stack hops. It's only worth its price if it buys a freedom — a decision, a transformation, a boundary. Otherwise it's a pure tax.

Le symptôme à reconnaîtreThe symptom to recognize

« Architecture lasagne » : des couches empilées par convention, où la plupart se contentent de redéléguer. Le signe : tu peux supprimer une couche et n'avoir qu'à recâbler les appels — elle ne décidait rien.'Lasagna architecture': layers stacked by convention, most just re-delegating. The tell: you can delete a layer and only need to rewire the calls — it decided nothing.

№ 03Le compteur de loyerThe rent meter5 min

Descends la pile. Pour chaque saut : décide-t-il, ou transmet-il ?Descend the stack. For each hop: does it decide, or forward?

Une seule règle de lecture : une couche vaut son saut si elle transforme, valide, décide, ou isole une frontière d'I/O. Si elle se contente de repasser l'appel, elle ajoute un cadre de pile et zéro liberté. L'animation suit l'appel vers le bas et tient deux compteurs : sauts qui paient leur loyer, et passe-plats.One reading rule: a layer earns its hop if it transforms, validates, decides, or isolates an I/O boundary. If it merely re-passes the call, it adds a stack frame and zero freedom. The animation follows the call downward and keeps two counters: hops that pay rent, and pass-throughs.

Animation — la pile à gauche, le compteur de loyer à droiteAnimation — the stack on the left, the rent meter on the right
Controllerpasse-platpass-through
↓
Servicepasse-platpass-through
↓
Managerpasse-platpass-through
↓
Repositorytransformetransforms
paient leur loyerpaying rent
0
passe-platspass-throughs
0
L'appel getUserEmail(42) entre dans le système. On descend la pile.The call getUserEmail(42) enters the system. We descend the stack.

1 / 6
La version saineThe healthy version

Deux couches au lieu de quatre : un point d'entrée qui orchestre, un Repository qui isole l'I/O. Les deux sauts paient leur loyer. On n'a pas « moins d'architecture » — on a retiré ce qui ne décidait rien.Two layers instead of four: an entry point that orchestrates, a Repository that isolates I/O. Both hops pay their rent. It's not "less architecture" — we removed what decided nothing.

Le motif transférable.The transferable pattern.

« Que décide cette couche ? » est le test universel d'une indirection. Il s'applique à un wrapper, un service, un microservice, un événement. Si la réponse est « elle transmet », tu paies un loyer sans louer d'espace.'What does this layer decide?' is the universal test of an indirection. It applies to a wrapper, a service, a microservice, an event. If the answer is 'it forwards', you're paying rent without renting space.

№ 04Le piègeThe trap4 min

Une frontière qui transforme, ou une couche qui redélègue.A boundary that transforms, or a layer that re-delegates.

Les deux extraits ajoutent de l'indirection. Mais l'un achète une liberté — le métier ne dépend plus du schéma SQL, il dépend d'un email validé — et l'autre n'achète rien : trois méthodes qui repassent l'argument tel quel. Bascule le toggle. La question n'est pas « combien de couches ? » mais « que décide chacune ? ».Both snippets add indirection. But one buys a freedom — the business no longer depends on the SQL schema, it depends on a validated email — and the other buys nothing: three methods re-passing the argument unchanged. Flip the toggle. The question isn't 'how many layers?' but 'what does each decide?'.

# une seule couture, et elle DÉCIDE
class UserRepository:
    def find_email(self, id) -> str:
        row = db.query("SELECT email FROM users WHERE id=?", id)
        if row is None:
            raise UserNotFound(id)          # ① une décision
        return row.email.lower().strip()    # ② une transformation
# le reste du code dépend d'un email validé, pas de SQL
Pourquoi c'est justeWhy it's right

Le Repository gagne son saut : il convertit un détail volatil (le schéma SQL) en une valeur métier stable (un email validé), et rend le reste testable sans base de données. Une seule frontière qui décide vaut mieux que quatre couches vides.The Repository earns its hop: it converts a volatile detail (the SQL schema) into a stable business value (a validated email), and makes the rest testable without a database. One boundary that decides beats four empty layers.

La règle qui tranche.The rule that settles it.

Le nombre de couches n'est jamais le problème — leur taux de décision l'est. Une couche qui transforme, valide, ou isole une frontière d'I/O paie son loyer, même seule. Une couche qui redélègue ne le paie jamais, même bien nommée. Supprime tout ce que tu peux retirer sans perdre une décision.The number of layers is never the problem — their decision rate is. A layer that transforms, validates, or isolates an I/O boundary pays its rent, even alone. A layer that re-delegates never does, however well named. Delete everything you can remove without losing a decision.

№ 05Bilan & éditoWrap-up & editorial2 min

Une frontière qui décide, ou un saut pour rien.A boundary that decides, or a hop for nothing.

Quand l'indirection paie, quand elle taxeWhen indirection pays, when it taxes
Saut pour rienHop for nothingLoyer payéRent paid
Que fait la coucheWhat the layer doesredélègue tel quelre-delegates as-istransforme / décide / isole l'I/Otransforms / decides / isolates I/O
ImplémentationsImplementationsune, pour toujoursone, foreverplusieurs, ou un test doubleseveral, or a test double
Si on la retireIf you remove itil suffit de recâblerjust rewireon perd une décisionyou lose a decision
Idée cléKey ideala lasagnelasagnala frontièrethe boundary

L'indirection paie quand…Indirection pays when…

  • elle traverse une frontière d'I/O : base de données, réseau, service tiers, système de fichiers.it crosses an I/O boundary: database, network, third-party service, filesystem.
  • il existe plusieurs implémentations réelles — ou ne serait-ce qu'une doublure de test qui rend le reste testable.there are several real implementations — or even just a test double that makes the rest testable.
  • elle transforme, valide ou décide : elle convertit un détail volatil en une valeur stable que le reste du code peut tenir pour acquise.it transforms, validates, or decides: it converts a volatile detail into a stable value the rest of the code can take for granted.

C'est de la cérémonie quand…It's ceremony when…

  • c'est un passe-plat 1-pour-1 perpétuel : une couche, une implémentation, à jamais.it's a perpetual 1-to-1 pass-through: one layer, one implementation, forever.
  • elle existe « au cas où » sans deuxième cas concret à l'horizon. C'est du YAGNI.it exists 'just in case' with no second concrete case on the horizon. That's YAGNI.
  • elle est là par habitude ou convention de framework, pas pour une frontière réelle.it's there out of habit or framework convention, not for a real boundary.

Mot de l'éditeurFrom the editor

L'indirection est l'outil principal de l'architecte et son vice principal — les deux à la fois. Le numéro précédent disait « isole l'axe qui change » ; celui-ci tient l'autre bout de la corde : chaque isolation a un loyer. La compétence n'est pas d'ajouter des couches, ni d'en retirer par principe — c'est de lire, saut par saut, si l'abstraction loue l'espace qu'elle facture.Indirection is the architect's main tool and main vice — both at once. The previous issue said 'isolate the axis that changes'; this one holds the other end of the rope: every isolation has rent. The skill isn't adding layers, nor removing them on principle — it's reading, hop by hop, whether the abstraction rents the space it bills for.

L'architecture lasagne n'est pas de la rigueur : c'est de la peur déguisée en rigueur — la peur de coupler, qu'on apaise en empilant des couches qui ne découplent rien.Lasagna architecture isn't rigor: it's fear dressed as rigor — the fear of coupling, soothed by stacking layers that decouple nothing.

Les voisins que ce numéro débloqueThe neighbors this issue unlocks

  • YAGNI — « You Aren't Gonna Need It » : la plupart des passe-plats sont des coutures posées pour un futur qui n'arrive jamais.'You Aren't Gonna Need It': most pass-throughs are seams placed for a future that never comes.
  • Dependency Inversion (Vol 1) — l'indirection qui, elle, paie toujours : retourner une flèche pour que le métier ne dépende plus du détail. Le bon usage du saut.the indirection that always pays: flipping an arrow so the business no longer depends on the detail. The good use of the hop.
  • Le point de non-retour (Vol 0 #3)The point of no return (Vol 0 #3) — le prochain numéro : certaines indirections sont faciles à ajouter plus tard, d'autres non. Savoir lesquelles change le calcul du loyer.the next issue: some indirections are easy to add later, others aren't. Knowing which changes the rent calculation.