Un atelier d'architecture · Édition d'ApprentissageAn Architecture Workshop · Learning Edition

Qu'est-ce qui change, qu'est-ce qui reste ?What changes, what stays?

Avant de choisir un pattern, on identifie l'axe qui va bouger — la donnée, le protocole, la règle — et on place la couture exactement là. Pas à l'endroit le plus complexe : à l'endroit le plus volatil.Before choosing a pattern, identify the axis that will move — the data, the protocol, the rule — and put the seam exactly there. Not at the most complex spot: at the most volatile one.

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
≈ 16 min●○○○MéthodeCouplageTradeoff
SommaireContents ·
01CadrageFraming3 min

La première question n'est pas « quelle structure ? ». C'est « qu'est-ce qui va changer ? ».The first question isn't "what structure?". It's "what is going to change?".

Devant une fonctionnalité, le réflexe du débutant est de choisir un pattern et de le plaquer. Celui de l'architecte est antérieur : repérer, dans le code, ce qui va bouger — et ce qui va rester. Prends un simple calcul de prix. Trois lignes côte à côte, qui semblent du même bloc. Elles changent en réalité à trois vitesses radicalement différentes.Faced with a feature, the beginner's reflex is to pick a pattern and slap it on. The architect's reflex comes first: spot, in the code, what will move — and what will stay. Take a simple price calculation. Three lines side by side, seemingly one block. They actually change at three radically different speeds.

Le même code, lu par vitesse de changementThe same code, read by rate of change
sous_total = somme(l.prix * l.quantité)
change : jamais — arithmétiquechanges: never — arithmetic
GeléeFrozen
tva = sous_total * 0.20
change : loi, payschanges: law, country
LenteSlow
remise = 0.10 si sous_total > 100
change : campagne marketingchanges: marketing campaign
RapideFast
Le réflexe du volumeThe volume's reflex

L'architecture ne sert pas l'élégance, elle sert le changement. Un design « beau » qui rend le changement attendu coûteux est mauvais ; un design quelconque qui l'absorbe en une ligne est bon. La seule question qui tranche : quel axe va bouger, et l'ai-je isolé du reste ?Architecture doesn't serve elegance, it serves change. A 'beautiful' design that makes the expected change costly is bad; a plain one that absorbs it in a single line is good. The only question that settles it: which axis will move, and have I isolated it from the rest?

Pourquoi ce numéro ouvre la série.Why this issue opens the series.

On ne choisit pas un pattern : on identifie l'axe de variation, puis on place la couture exactement là où il passe. Couplage, couches, repository, microservices — tous les numéros qui suivent ne sont que des manières de tenir une couture une fois qu'on sait où la mettre. Avant le pattern, le diagnostic.You don't pick a pattern: you identify the axis of variation, then place the seam exactly where it runs. Coupling, layers, repository, microservices — every issue that follows is just a way to hold a seam once you know where to put it. Before the pattern, the diagnosis.

02La douleurThe pain4 min

Le piège n'est pas d'oublier d'abstraire. C'est d'abstraire au mauvais endroit.The trap isn't forgetting to abstract. It's abstracting in the wrong place.

On met une couture là où le code paraît compliqué, pas là où il va changer. Et les deux coïncident rarement. Le développeur consciencieux voit l'arithmétique du sous-total, la trouve « centrale », et l'isole derrière une belle abstraction. Il est fier : c'est extensible, testable, propre. Sauf que le sous-total ne change jamais.We place a seam where the code looks complex, not where it will change. And the two rarely coincide. The conscientious developer sees the sub-total arithmetic, deems it 'central', and isolates it behind a clean abstraction. Proud: it's extensible, testable, tidy. Except the sub-total never changes.

La couture posée sur l'axe le plus stable — pour rienA seam placed on the most stable axis — for nothing
interface StratégieDeCalcul:
    calculer(lignes) -> Montant          # ← belle abstraction…

class CalculStandard implements StratégieDeCalcul:
    def calculer(lignes):
        return somme(l.prix * l.quantité)  # …sur ce qui ne bouge JAMAIS

# pendant ce temps, les vrais axes volatils restent codés en dur :
def total(lignes, stratégie):
    st = stratégie.calculer(lignes)
    tva = st * 0.20                       # ✗ figé au milieu de la fonction
    remise = st * 0.10 si st > 100        # ✗ figé, change chaque sprint
Ce que ça coûteWhat it costs

Le jour où le métier annonce « TVA à 5,5 % sur l'alimentaire », on rouvre la fonction de calcul — celle qu'on croyait protégée — et on la charcute. L'abstraction qu'on a construite garde un axe immobile ; le vrai axe de variation, lui, traverse le code sans aucune couture pour l'absorber.The day the business announces "5.5% tax on groceries", we reopen the calculation function — the one we thought protected — and gut it. The abstraction we built guards a motionless axis; the real axis of variation runs through the code with no seam at all to absorb it.

Le diagnostic.The diagnosis.

Le problème n'est pas un manque d'abstraction — il y en a une. C'est qu'elle est posée sur le mauvais axe. Une couture ne vaut que par ce qu'elle laisse varier de chaque côté. Séparer deux choses qui bougent ensemble n'ajoute pas une liberté : juste un nom et une indirection.The problem isn't a missing abstraction — there is one. It's placed on the wrong axis. A seam is only worth what it lets vary on each side. Separating two things that move together adds no freedom: just a name and an indirection.

Le détecteur honnête : le testThe honest detector: the test
def test_tva_alimentaire():
    # impossible à écrire proprement :
    # le taux est noyé dans total(),
    # aucune couture où injecter
    # une autre règle de TVA.
03La coutureThe seam5 min

Place la couture sur l'axe qui bouge. Puis regarde ce que chaque changement rouvre.Put the seam on the axis that moves. Then watch what each change reopens.

La méthode tient en trois temps, et aucun ne nomme un pattern : énumère les responsabilités, demande pour chacune « qu'est-ce qui la ferait changer, et à quelle fréquence ? », puis place la couture entre deux axes qui bougent à des vitesses différentes. Le sous-total reste du code nu ; la TVA et la remise deviennent des fonctions injectées. L'animation fait défiler les changements réels et montre, à chaque fois, le rayon d'explosion.The method is three steps, none naming a pattern: list the responsibilities, ask of each 'what would make it change, and how often?', then place the seam between two axes that move at different speeds. The sub-total stays bare code; tax and discount become injected functions. The animation rolls real changes through and shows, each time, the blast radius.

Animation — le changement à gauche, ce qu'on rouvre à droiteAnimation — the change on the left, what we reopen on the right
changement entrantincoming change
Le système tourne. Les demandes de changement arrivent…The system is running. Change requests start arriving…
cœur métier rouvertbusiness core reopened : 0 / 3 attendusexpected
cœur stablestable core
def sous_total(lignes): …
def total(lignes, tva, remise): …
── la couturethe seam ──
axe volatil · injectévolatile axis · injected
règle_tva(st, lignes)
axe volatil · injectévolatile axis · injected
règle_remise(st, lignes)
Le cœur (sous_total + total) est stable. Les deux règles volatiles sont injectées, posées sur la couture.The core (sub_total + total) is stable. The two volatile rules are injected, sitting on the seam.

1 / 6
La couture révèle le testThe seam reveals the test
def test_remise_campagne():
    remise = lambda st, _: st*0.10 if st>100 else 0
    assert total(panier, tva_std, remise) == 119.7
    # on teste la règle volatile seule, sans rien d'autre
Le motif transférable.The transferable pattern.

Identifier l'axe précède tout pattern. Selon sa nature, il prendra un nom : Strategy si c'est un comportement, Repository si c'est le stockage, Adapter si c'est un protocole. Mais le nom vient après — d'abord « qu'est-ce qui change ? », ensuite l'outil qui tient cette couture.Identifying the axis precedes any pattern. Depending on its nature it takes a name: Strategy for a behavior, Repository for storage, Adapter for a protocol. But the name comes after — first 'what changes?', then the tool that holds that seam.

04Le piègeThe trap4 min

Le piège de jugement : confondre « compliqué » et « volatil ».The judgment trap: mistaking "complex" for "volatile".

On isole ce qui est difficile à comprendre, en croyant isoler ce qui va changer. Ce sont deux propriétés indépendantes. La complexité d'un bout de code ne justifie jamais à elle seule une couture — seule sa probabilité × fréquence de changement la justifie. Bascule le toggle : les deux versions ont une couture, mais une seule est posée sur le bon axe.We isolate what's hard to understand, believing we isolate what will change. These are independent properties. A snippet's complexity alone never justifies a seam — only its probability × frequency of change does. Flip the toggle: both versions have a seam, but only one is placed on the right axis.

# le cœur stable reste nu — pas de cérémonie
def sous_total(lignes):
    return sum(l.prix * l.quantité for l in lignes)

# l'axe VOLATIL devient un paramètre (la couture est ici)
def total(lignes, règle_tva, règle_remise):
    st = sous_total(lignes)
    return st + règle_tva(st, lignes) - règle_remise(st, lignes)
Pourquoi c'est justeWhy it's right

Le cœur stable reste du code ordinaire, sans interface. Les deux règles volatiles sont des fonctions injectées : changer la remise du mois, c'est passer une autre fonction, pas rouvrir total(). La couture est posée exactement sur l'axe qui bouge.The stable core stays ordinary code, no interface. The two volatile rules are injected functions: changing this month's discount means passing a different function, not reopening total(). The seam sits exactly on the axis that moves.

La nuance fonctionnelle.The functional nuance.

Une couture sur un axe de comportement n'a pas besoin d'interface ni de classe : une fonction passée en paramètre suffit (règle_remise ci-dessus). « Extraire une Strategy » et « passer une fonction » sont souvent le même geste. Le pattern n'est pas la couture ; il est un emballage de la couture quand le langage l'exige. (On y revient au Vol 3.)A seam on a behavioral axis needs no interface or class: a function passed as a parameter suffices (règle_remise above). 'Extract a Strategy' and 'pass a function' are often the same move. The pattern isn't the seam; it's a wrapper for the seam when the language demands one. (More in Vol 3.)

05Bilan & éditoWrap-up & editorial2 min

La forme d'abord, ou le mouvement d'abord.Form first, or motion first.

Les deux postures, côte à côteThe two postures, side by side
Par structureBy structurePar axe de variationBy axis of variation
Première questionFirst questionquel pattern ?which pattern?qu'est-ce qui change ?what changes?
Où va la coutureWhere the seam goesoù c'est complexewhere it's complexoù c'est volatilwhere it's volatile
Changement attenduExpected changerouvrir le cœurreopen the corepasser un paramètrepass a parameter
Idée cléKey ideala formethe formle mouvementthe motion

Quand ne pas poser de coutureWhen not to place a seam

  • L'axe est imaginaire.The axis is imaginary. « On pourrait un jour changer de base » sans besoin ni échéance, c'est du YAGNI déguisé en prudence. On attend le deuxième cas concret.'We might one day swap databases' with no real need or deadline is YAGNI dressed as prudence. Wait for the second concrete case.
  • Les deux côtés bougent ensemble.Both sides move together. Si A et B changent toujours en même temps et pour la même raison, une couture entre eux n'ajoute qu'un saut. On les laisse soudés.If A and B always change together for the same reason, a seam between them only adds a hop. Leave them welded.
  • L'indirection coûte plus que le changement.The indirection costs more than the change. Un script jetable, un prototype : l'élégance y est un luxe que le contexte ne paie pas.A throwaway script, a prototype: elegance there is a luxury the context won't pay for.

Mot de l'éditeurFrom the editor

Tout le reste de la série découle de ce numéro. Le couplage, les couches, le repository, le découpage en services : ce sont des réponses à « qu'est-ce qui change ? », jamais des points de départ. Le débutant collectionne des structures et cherche où les plaquer. L'architecte regarde un système et voit d'abord ses lignes de faille — les endroits où le futur va appuyer.Everything else in the series flows from this issue. Coupling, layers, repository, splitting into services: these are answers to 'what changes?', never starting points. The beginner collects structures and looks for where to slap them on. The architect looks at a system and first sees its fault lines — the places where the future will press.

Poser une couture ailleurs, c'est se rassurer en payant un loyer pour une assurance qu'on ne touchera jamais. Un pattern bien placé — surtout quand on sait pourquoi — en vaut vingt mémorisés.Placing a seam elsewhere is reassuring yourself by paying rent on insurance you'll never claim. One well-placed pattern — especially when you know why — is worth twenty memorized.

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

  • Information Hiding (Parnas, 1972)l'ancêtre direct : un module doit cacher la décision susceptible de changer. « Axe de variation » et « secret d'un module » sont la même idée à cinquante ans d'écart.the direct ancestor: a module must hide the decision likely to change. 'Axis of variation' and 'a module's secret' are the same idea fifty years apart.
  • Open/Closed Principlesa conséquence : un module bien coupé est ouvert à l'extension sur son axe volatil, fermé à la modification de son cœur stable.its consequence: a well-cut module is open to extension on its volatile axis, closed to modification of its stable core.
  • Le coût caché de l'indirectionThe hidden cost of indirectionle contre-poids, et le sujet du prochain numéro (Vol 0 #2) : chaque couture se paie ; une abstraction qui ne protège aucun axe réel est une dette.the counterweight, and the next issue's subject (Vol 0 #2): every seam has a price; an abstraction guarding no real axis is debt.
Retour au kiosqueBack to newsstand