Vous souhaitez nous soutenir ? Devenez sponsor de l'association sur notre page Github

La méthode Mikado à la rescousse de nos refactos !

Publié le 18 novembre 2025 par William Suppo
Couverture de l'article La méthode Mikado à la rescousse de nos refactos !

Découvrons ensemble la méthode Mikado qui nous aide à refactoriser de manière itérative et logique notre code.

Qu'est-ce que la méthode Mikado ?

Cette méthode tire son nom du fameux jeu de société Mikado où le principe est simple : retirer chaque baguette les unes à la suite des autres sans faire bouger les autres afin d'en recueillir un maximum !

Dans le cadre de notre refactorisation l'idée s'en rapproche fortement car on va chercher à faire de petites itérations qui suive une logique implacable : dès qu'une portion de notre code vacille alors on arrête, on remet notre code à son état d'origine et on envisage une étape intermédiaire afin d'atteindre l'objectif !

Les 4 étapes de la méthode Mikado

La première étape de notre refactorisation est la définition de l'objectif à atteindre, notre cible finalement, un exemple : Je souhaite extraire la logique d'envoi d'email de mon contrôleur vers un service dédié

La deuxième étape consiste à effectuer directement une tentative de modification de notre code, comme habituellement.

On arrive ensuite à la troisième étape qui est l'observation : on constate ici si nos tests passent toujours ou bien si on a des dépendances cassées qui nécessiterai une étape intermédiaire dans notre processus de refactorisation.

Cela nous amène à la quatrième étape : Chaque observation effectué dans la troisième devient un sous-objectif matérialiser par un nœud dans notre arbre.

À ce moment là, notre sous-objectif devient notre nouvel objectif à atteindre et on réitère nos 4 étapes jusqu'à ne rencontrer plus aucun obstacle !

Ainsi nous avons construit notre arbre des dépendances où chaque nœud est une étape à passer avant d'atteindre notre objectif premier. Chaque étape a un périmètre maitrisé et peu être déployé en production en évitant tout effet de bord.

Bravo vous avez obtenu l'empereur du Japon, le Mikado !

Démonstration par l'exemple

Dans cette nouvelle partie de Mikado, nous allons partir du code suivant :

1 class UserController
2 {
3 public function register(array $data)
4 {
5 $db = new PDO('mysql:host=localhost;dbname=app', 'root', '');
6 $stmt = $db->prepare("INSERT INTO users (email, password) VALUES (?, ?)");
7 $stmt->execute([$data['email'], md5($data['password'])]);
8 
9 mail(
10 $data['email'],
11 "Bienvenue !",
12 "Merci de vous être inscrit sur notre site."
13 );
14 
15 echo "Inscription réussie pour " . $data['email'];
16 }
17}

On constate que beaucoup d'aspects ne vont pas au sein de notre contrôleur alors définissons ensemble notre objectif initial : Extraire de notre contrôleur la logique d'enregistrement d'un utilisateur

Ce sera ainsi l'ultime nœud dans notre arbre :

On commence le développement par la création d'un UserService qui va avoir la responsabilité d'enregistrer puis de notifier l'utilisateur, ce qui nous ajoute de fait un nouveau nœud dans notre arbre qui dépend de notre objectif initial : Créer un UserService qui déclenche la sauvegarde en base et la notification

Voici l'implémentation de notre nouveau service :

1class UserService
2{
3 public function registerUser(array $data)
4 {
5 $db = new PDO('mysql:host=localhost;dbname=app', 'root', '');
6 $stmt = $db->prepare("INSERT INTO users (email, password) VALUES (?, ?)");
7 $stmt->execute([$data['email'], md5($data['password'])]);
8 
9 mail(
10 $data['email'],
11 "Bienvenue !",
12 "Merci de vous être inscrit sur notre site."
13 );
14 }
15}

Bon, on vient de déporter le problème dans un service, c'est déjà ça, mais essayons de voir plus loin en visant la responsabilité unique au sein de celui-ci.

L'idée est de séparer la logique d'enregistrement de l'utilisateur et celle qui le notifie dans deux classes distinctes, on va donc s'ajouter 2 nouveaux objectifs :

  • Créer un UserRepository qui sauvegarde l’utilisateur en base
  • Créer un MailerService qui notifie l’utilisateur

Ces objectifs sont représentés par des nœuds qui dépendent du second objectif qu'on s'est fixé, comme ceci :

Nous voilà revenu à la case départ pour ce qui est du code, pour rappel notre UserController est intact et le UserService n'existe pas encore.

Nous sommes donc face à notre arbre et nous allons choisir de traiter l'un des objectifs à sa base, par exemple Créer un UserRepository qui sauvegarde l’utilisateur en base, dont une idée d'implémentation peut-être la suivante :

1class UserRepository
2{
3 private PDO $db;
4 
5 public function __construct(PDO $db)
6 {
7 $this->db = $db;
8 }
9 
10 public function save(string $email, string $password): void
11 {
12 $stmt = $this->db->prepare("INSERT INTO users (email, password) VALUES (?, ?)");
13 $stmt->execute([$email, md5($password)]);
14 }
15}

On peut très bien imaginer qu'en accompagnement de cette classe, on y ajoute quelques tests unitaires, dans tous les cas nous allons publier le code dans une version qui ne contient qu'elle et ses tests et surtout pas de modification sur UserController, ce sera notre dernière étape, rappelez-vous !

Avant l'implémentation de UserRepository, on aurait pu ajouter une étape intermédiaire dans notre arbre, qui est la création d'un modèle Eloquent User, modèle qui aurait été utilisé ensuite dans notre UserRepository.

On continue la progression dans notre arbre avec le second nœud à la base de notre arbre : Créer un MailerService qui notifie l’utilisateur :

1class MailerService
2{
3 public function sendWelcomeEmail(string $email): void
4 {
5 mail($email, "Bienvenue !", "Merci de vous être inscrit sur notre site.");
6 }
7}

On agrémente notre classe d'un petit test unitaire et on publie le code pour valider cette étape. Bravo, on a traité la base de notre arbre !

Étape suivante, on remonte d'un cran, nous voici face à l'objectif Créer un UserService qui déclenche la sauvegarde en base et la notification. On va enfin modifier notre code existant, mais de façon sereine, car nous avons maintenant à notre disposition les classes UserRepository et MailerService toutes neuves et testées !

Voici notre nouveau UserService, tout beau, tout neuf, qui utilise nos nouvelles classes :

1class UserService
2{
3 public function __construct(
4 private UserRepository $repo,
5 private MailerService $mailer
6 ) {}
7 
8 public function registerUser(array $data): void
9 {
10 $this->repo->save($data['email'], $data['password']);
11 $this->mailer->sendWelcomeEmail($data['email']);
12 }
13}

On applique ensuite la même philosophie : un petit test unitaire avec la possibilité de mocker facilement les dépendances à UserRepository et MailerService, on publie et on valide cet objectif !

Nous voilà désormais arrivés à l'ultime étape de notre arbre : Extraire de notre contrôleur la logique d'enregistrement d'un utilisateur ! On va pour cela utiliser notre UserService dans le UserController comme ceci :

1class UserController
2{
3 public function __construct(
4 private UserService $service,
5 ) {}
6 
7 public function register(array $data)
8 {
9 $this->service->registerUser($data);
10 
11 echo "Inscription réussie pour " . $data['email'];
12 }
13}

On test, on publie et ... Eurêka ! Nous voilà rendus à la fin de notre refacto !

On a pu, ainsi, appréhender notre refacto étape par étape et de manière logique, ce qui nous a permis de faire des petites livraisons avec un impact sur le code maîtrisé, bravo !

Autre bonus et non des moindre si on travaille en équipe, c'est qu'on a pu soumettre en relecture à nos camarades des portions de code modifié plus légère et donc moins sujettes à des louper !

Voilà pour cette introduction à la méthode Mikado que j'ai pu exercé personnellement sur des refactos qui, sur le papier, étaient ambitieuses et qui m'auraient values quelques nœuds au cerveau.

William Suppo avatar
William Suppo
Je mange du PHP au p'tit dej', et vous ?

A lire

Autres articles de la même catégorie