Résumé
Mon article précédent extrayait des conditions dans des fonctions sur des cas simples. Les situations plus compliquées ne se règlent pas par une extraction, et celui-ci en prend une: évaluer une expression comme 1 + (6 + 5) * 8 en respectant l’associativité et la priorité des opérateurs.
La première solution est celle que tout le monde écrit: une classe Expression avec un opérateur, une opérande gauche et une opérande droite, et un switch pour évaluer. Elle marche, et elle viole le principe ouvert/fermé, puisque chaque nouvel opérateur oblige à modifier le switch. Le polymorphisme corrige cela: une Expression abstraite, une ValueExpression pour les valeurs, une OperatorExpression par opérateur, et un nouvel opérateur devient une nouvelle classe sans toucher aux autres.
Mais le polymorphisme seul ne tient pas face à une expression profondément imbriquée. D’où le pattern interpréteur, posé par-dessus: un Lexer qui découpe la chaîne en jetons, un Parser qui les réordonne selon la priorité avec un algorithme inspiré du tri fusion, et un Interpréteur qui les évalue avec une pile. Le pattern stratégie n’a pas disparu; il sert encore à évaluer chaque opération, via une Map d’opérateurs.
Ce qui a rendu la démarche possible, ce sont les tests Jest écrits avant et mis à jour à chaque étape: aucune modification n’est acceptée sans qu’ils passent. Le dépôt garde une branche par étape.
Idées clés
- Un switch dans l’évaluateur viole le principe ouvert/fermé: chaque nouvel opérateur modifie du code existant.
- Le polymorphisme, une classe par opérateur, rend l’ajout d’un opérateur trivial et supprime le switch.
- Face aux expressions imbriquées, un lexer, un parser et un interpréteur prennent le relais, et le pattern stratégie reste sous l’interpréteur.
- Les attentes Jest, écrites d’abord et mises à jour à chaque étape, sont ce qui rend le refactoring vérifiable.
Pourquoi j’ai écrit cet article
Dans mon article précédent, nous avions exploré comment extraire des conditions dans des fonctions sur des cas simples et pratiques. Les situations plus compliquées ne se règlent pas par de simples extractions.