Aller au contenu

Dette technique

Identifier, classifier et gérer la dette technique — un levier strategique quand elle est délibérée, un risque systémique quand elle est invisible.


Définition

Le terme "dette technique" a été introduit par Ward Cunningham en 1992. L'analogie avec la dette financiere est délibérée : on emprunte de la vitesse à court terme en acceptant un coût de maintenance à long terme. Comme pour la dette financiere, le problème n'est pas d'en avoir — c'est de ne pas savoir combien on en a, ni de ne pas la rembourser.

La dette technique, ce n'est pas du "mauvais code". C'est l'ecart entre l'état actuel du système et l'état qu'il devrait avoir pour supporter les exigences actuelles et a venir. Cet ecart peut être délibéré (on a fait un choix pragmatique en connaissance de cause) ou involontaire (on ne savait pas qu'on créait de la dette).


Le quadrant de Fowler

Martin Fowler a propose un quadrant qui classe la dette technique selon deux axes : délibérée vs involontaire, et prudente vs imprudente.

quadrantChart
    title Quadrant de la dette technique
    x-axis "Imprudente" --> "Prudente"
    y-axis "Involontaire" --> "Deliberee"
    quadrant-1 "Deliberee + Prudente"
    quadrant-2 "Deliberee + Imprudente"
    quadrant-3 "Involontaire + Imprudente"
    quadrant-4 "Involontaire + Prudente"
Quadrant Exemple Posture
Délibérée + Prudente "On livre sans cache, on l'ajoutera quand le trafic le justifiera" Acceptable — documenter dans un ADR
Délibérée + Imprudente "On n'a pas le temps de concevoir, on code directement" Dangereuse — souvent sous-estimée
Involontaire + Prudente "On ne connaissait pas le pattern CQRS quand on a commence" Naturelle — on apprend en construisant
Involontaire + Imprudente "C'est quoi les bounded contexts ?" Structurelle — nécessité formation

La dette délibérée et prudente est la seule forme acceptable à long terme. Les autres formes doivent être identifiées et traitees avant qu'elles ne deviennent systemiques.


Identification de la dette technique

La dette technique est souvent invisible dans les outils de suivi classiques. On la détecté par plusieurs signaux complementaires.

Métriques de code

Métrique Outil Signal de dette
Complexité cyclomatique radon, lizard > 15 par fonction
Couplage afferent/efferent jdepend, deptry Ratio instabilite proche de 0.5
Duplication de code jscpd, CPD > 5% du codebase
Taille des fichiers cloc, tokei > 500 lignes par fichier
Âge du code non modifie git log Modules critiques non touches > 1 an
Couverture de tests pytest-cov, istanbul < 60% sur les modules core

Analyse de couplage

Le couplage est le premier indicateur de dette architecturale. Un système fortement couple résisté au changement — modifier un module en casse trois autres.

# analyse_couplage.py
# Mesure le couplage entre modules via les imports
from pathlib import Path
import ast
from collections import defaultdict

def analyse_coupling(src_dir: str) -> dict[str, list[str]]:
    """Construit le graphe de dependances entre modules."""
    deps = defaultdict(set)
    for py_file in Path(src_dir).rglob("*.py"):
        module = py_file.parts[1] if len(py_file.parts) > 1 else None
        if not module:
            continue
        with open(py_file) as f:
            try:
                tree = ast.parse(f.read())
            except SyntaxError:
                continue
        for node in ast.walk(tree):
            if isinstance(node, ast.ImportFrom) and node.module:
                parts = node.module.split(".")
                if len(parts) > 1 and parts[0] == "src":
                    target = parts[1]
                    if target != module:
                        deps[module].add(target)
    return {k: sorted(v) for k, v in deps.items()}

Velocite de l'équipe

La dette technique se manifeste aussi dans les métriques d'équipe :

  • Temps de livraison croissant — les features simples prennent de plus en plus de temps
  • Ratio bug/feature croissant — on passe plus de temps a corriger qu'a construire
  • Onboarding lent — les nouveaux développeurs mettent des semaines a être productifs
  • Zones de code "intouchables" — des modules que personne n'ose modifier
  • Contournements fréquents — les développeurs ajoutent des couches d'abstraction plutôt que de corriger le problème sous-jacent
  • Reviews de plus en plus longues — la complexité du code rend les revues plus difficiles et plus longues

Note

La velocite de l'équipe est le signal le plus fiable de dette technique. Les métriques de code sont des indicateurs — la velocite est la conséquence réelle.


Classification : sévérité et effort

Une fois la dette identifiée, on la classe selon deux axes pour prioriser le traitement.

Matrice sévérité x effort

quadrantChart
    title Priorisation de la dette technique
    x-axis "Effort faible" --> "Effort eleve"
    y-axis "Severite faible" --> "Severite elevee"
    quadrant-1 "Planifier"
    quadrant-2 "Quick wins"
    quadrant-3 "Reporter"
    quadrant-4 "Ignorer"
Quadrant Action Exemple
Quick wins Traiter immédiatement Renommer un module mal nomme
Planifier Intégrer dans le prochain cycle Extraire un service couple
Reporter Documenter, surveiller, traiter quand l'effort diminue Migration de framework
Ignorer Accepter explicitement (dette prudente) Code legacy stable non modifie

Scoring de la dette

Pour chaque item de dette identifié, on attribue un score sur trois dimensions :

  • Impact (1-5) : conséquence sur la velocite, la fiabilité, la sécurité
  • Probabilite d'aggravation (1-5) : risque que la dette empire si non traitee
  • Effort de remédiation (1-5) : coût de correction en jours-équipe

Le score de priorité = (Impact * Probabilite) / Effort. Les items avec le score le plus élevé sont traites en premier.


Stratégies de remédiation

Boy scout rule

"Laisse le code un peu plus propre que tu ne l'as trouve." Chaque PR qui touche a une zone de dette inclut une amélioration incrementale. Pas de refactoring massif — des petites améliorations constantes.

Efficace pour la dette de faible sévérité et de faible effort. Inefficace pour la dette structurelle qui nécessité un changement coordonné.

Tech debt sprints

Dedier régulièrement du temps au remboursement de la dette. Deux modèles :

  • Pourcentage fixe : 20% du temps de chaque sprint est réservé à la dette technique. Simple a mettre en place, difficile à maintenir quand la pression augmente.
  • Sprint dédié : un sprint sur quatre ou cinq est entièrement dédié à la dette. Plus visible, plus impactant, mais crée un cycle "on accumule puis on rembourse".

Strangler fig pattern

Pour la dette structurelle massive (monolithe a decomposer, migration de stack), le strangler fig pattern permet de remplacer progressivement un système existant sans big bang.

flowchart LR
    CLIENT["Client"] --text--> PROXY["Proxy / Gateway"]
    PROXY --"ancien"--> LEGACY["Systeme legacy"]
    PROXY --"nouveau"--> NEW["Nouveau systeme"]
    LEGACY -.->|"migration\nprogressive"| NEW

Le principe : on intercale un proxy devant le système existant. Les nouvelles fonctionnalités vont dans le nouveau système. Les anciennes fonctionnalités sont migrees progressivement. Le système legacy retrecit jusqu'à disparaitre.

Refactoring continu

Le refactoring n'est pas un projet — c'est une pratique quotidienne. Les refactorings structurels (extraction de module, changement de pattern de communication) sont planifies comme des features. Les refactorings locaux (simplification, renommage, extraction de fonction) sont faits au fil de l'eau.


Tracking de la dette

Backlog de dette technique

La dette technique doit avoir son propre backlog, visible et priorise. Chaque item de dette est un ticket avec :

  • Description : qu'est-ce qui ne va pas ?
  • Impact : quelle conséquence si on ne fait rien ?
  • Proposition : quelle approche de remédiation ?
  • Score : priorité calculee (impact * probabilite / effort)
  • Owner : qui est responsable du suivi ?

Fitness functions comme gardes

Les fitness functions (chapitre précédent) servent aussi de gardes contre l'aggravation de la dette. Une fois qu'on a identifié un problème de couplage, on pose une fitness function qui empêche le couplage d'augmenter — même si on ne le réduit pas immédiatement.

# fitness/test_coupling_guard.py
COUPLING_BASELINE = {
    "order": {"catalog": 3},  # 3 imports existants (dette connue)
    "notification": {"order": 1},
}

def test_coupling_does_not_increase():
    """La dette de couplage ne doit pas augmenter."""
    current = analyse_coupling("src")
    for module, deps in COUPLING_BASELINE.items():
        for target, max_count in deps.items():
            actual = count_imports(module, target)
            assert actual <= max_count, (
                f"Couplage {module} -> {target} a augmente: "
                f"{actual} > {max_count} (baseline)"
            )

Communication de la dette au management

La dette technique est un concept d'ingénierie. Le management raisonne en termes de risques, de coûts et de délais. Pour obtenir du temps pour rembourser la dette, il faut traduire.

Le langage du risque

Ne pas dire : "il faut refactorer le module Order". Dire : "le module Order a un couplage critique qui fait que chaque nouvelle feature prend 3 fois plus de temps que prévu. Si on ne le traite pas, le prochain release cycle prendra 8 semaines au lieu de 3."

Métriques parlantes

Métrique technique Traduction management
Complexité cyclomatique > 25 Chaque modification risque d'introduire un bug
Couverture tests < 40% On ne détecté les bugs qu'en production
5 dépendances avec CVE critique Risque de sécurité non couvert
Couplage inter-modules élevé Impossible de livrer un module sans toucher 3 autres

Visualiser la tendance

Un graphique montrant l'évolution du temps de livraison par feature sur 6 mois est plus convaincant que n'importe quel argumentaire technique. Si la courbe monte, la dette est en train de gagner.

Tableau de bord de dette

Indicateur Source Tendance souhaitee
Nombre d'items de dette Backlog Stable ou baissier
Score total de dette Backlog (somme) Baissier
Ratio dette / features Sprint metrics < 20%
Complexité cyclomatique moyenne SonarQube, radon Stable ou baissier
Couverture de tests CI Croissant
Temps de livraison moyen DORA metrics Stable ou baissier

Tip

La dette technique zero n'existe pas — et n'est pas souhaitable. L'objectif est de maintenir la dette à un niveau maîtrise et délibéré, pas de l'éliminer. On géré la dette technique comme on géré la dette financiere : on sait combien on doit, on paie les intérêts, et on rembourse le principal quand c'est strategiquement pertinent.

Chapitre suivant : Architecture Repository — centraliser les standards, patterns et décisions dans un référentiel vivant.