Accueil / Articles / Les design patterns
Les design patterns
Publié le 3 Mars 2025
Les patrons de conception (“design patterns”, “patterns” ou encore “patrons”), sont des concepts liés au code et qui vont répondre à des problématiques récurrentes qu’un développeur peut rencontrer lors de la conception d’un programme informatique. Le but d’un design pattern est de vous proposer un concept qui va résoudre d’une façon simple et élégante votre problématique. Le rôle du développeur sera de retranscrire et d’adapter ces concepts dans son code. Pour un même pattern, le code implémenté d’un programme à un autre peut être complètement différent.
Utilité du design pattern
Les patterns vous proposent des solutions standardisées et réutilisables. Qui dit standardisé signifie compréhensible par le plus grand nombre; la communication entre développeurs est plus simple. Les patterns vont vous permettre d’écrire du code plus flexible et plus évolutif.
Les inconvénients des design patterns
Nous, les développeurs, adorons montrer aux autres qu’on connaît pleins de choses, et pour ça, il nous arrive d'ajouter (inutilement) de la complexité un peu partout dans le code. Les patterns peuvent être des outils très puissants pour le développeur qui les maîtrise. Mais comme tout outil, il doit être utilisé judicieusement et avec parcimonie.
Sur des projets simples ou lorsqu’on débute un nouveau programme, il est souvent recommandé de ne pas utiliser de design patterns. Leur utilisation a tendance à ajouter de la complexité au code; au détriment de la compréhension et de la lisibilité.
Certains de ces patterns sont plus complexes et vont demander au préalable une maîtrise de certains concepts de la programmation orientée objet. Pour des débutants en programmation, il n’est pas non plus recommandé d’utiliser des patterns.
Je n’ai jamais utilisé de design patterns. Cela fait-il de moi un mauvais développeur ?
La réponse courte est…. absolument pas !
L’utilisation d’un ou plusieurs patterns n’est pas obligatoire pour concevoir un bon programme. Tout va dépendre du projet sur lequel vous travaillez. Toujours privilégier la simplicité et la compréhension du code !
J’ai déjà utilisé certains patterns en entreprise ou pour mes projets personnels, mais je suis loin de les avoir tous testés ou utilisés en milieu professionnel (et je ne sais pas si ça sera le cas un jour).
L'utilisation des patterns va dépendre de la logique métier liée à l’activité d’une entreprise et des problématiques que vous êtes susceptibles de rencontrer dans la conception de vos programmes. Il faut savoir utiliser un outil quand celui-ci nous sert vraiment. Personne n’utilise un marteau coûte que coûte au motif que c’est son outil préféré.
Tout au long de votre apprentissage du code et de votre expérience, vous allez probablement, sans le savoir, utiliser des patterns. Le simple fait d’appliquer des bonnes pratiques dans votre code (fonctions avec des rôles bien définis, séparation des responsabilités, réduction des dépendances/couplages entre vos classes, etc…) vous dirige naturellement (dans certains cas) vers leurs utilisations.
Origine des design patterns
On ne peut pas vraiment parler d’inventeur ou de créateur des designs patterns. Les différents patterns ont été développés tout au long de l’évolution de la programmation et de l’informatique.
Ils ont été popularisés pour la première fois en 1994 dans le livre Design Patterns: Elements of Reusable Object-Oriented Software écrit par Erich Gamma, Richard Helm, Ralph Johnson et John Vlissides, connus sous le nom de “Gang of four” (GoF). Le livre nous présente une liste de 23 designs patterns considérés comme des classiques dans la programmation et regroupés en trois catégories (patterns de conception, patterns structuraux et patterns comportementaux). Il existe d’autres patterns en dehors de cette liste, mais dans cet article, nous allons nous concentrer sur les classiques.
Présentation des différents patterns
Voici une présentation très générale et très simplifiée des design patterns regroupés par catégorie. Nous aborderons plus en détails, chacun des patterns de la liste dans des articles dédiés.
Les patterns de conception
Abstract Factory : permet de gérer la création de plusieurs objets de la même famille.
Builder : permet de créer un objet étape par étape en fournissant une méthode pour obtenir l’instance d’une classe (un objet donc).
Factory : permet d’avoir une classe dédiée à la création d’objets.
Prototype : permet de créer par clonage un objet à partir d’un autre objet similaire et de le modifier selon ses besoins.
Singleton : garantit d’avoir une seule et unique instance d’une classe et un point d’accès global.
Les patterns structuraux
Adapter : permet de faire fonctionner deux classes incompatibles entre elles à l’aide d’une implémentation intermédiaire.
Bridge : permet de séparer abstraction (une interface générale) et implémentation (les détails, le concret).
Composite : permet d’organiser des objets dans une arborescence (hiérarchie) et de les traiter de manière uniforme (par exemple : dossier / sous-dossiers / fichiers).
Decorator : permet d’altérer le fonctionnement initial d’un objet et d’y ajouter des comportements de façon dynamique, sans modifier la structure de l'objet de base.
Facade : ajoute une ou des interfaces pour un accès simplifié à un service ou une librairie en cachant les détails d'implémentations.
Flyweight : favorise la réutilisation des objets et limite l’utilisation de ressources (comme la mémoire).
Proxy : joue un rôle de remplaçant / d'intermédiaire d’un objet et récupère les appels faits au véritable objet.
Les patterns comportementaux
Chain of responsibility : permet de propager une requête à travers une chaîne d’objets. Chacun des objets de la chaîne peut appliquer (ou non) un traitement à la requête.
Command : permet de transformer une requête ou une action en objet, qui pourra être ensuite exécuté, mis en attente ou annulé.
Interpreter : permet de transformer des expressions en objets et ensuite de les évaluer. Par exemple, un langage de requête comme DQL (Doctrine Query Language) s’appuie sur ce principe.
Iterator : permet de parcourir une liste d’objets.
Mediator : force des objets à communiquer entre eux par l'intermédiaire d’un objet dédié (le médiateur).
Memento : permet de sauvegarder l’état d’un objet, pour le restaurer plus tard dans un programme.
Observer : permet d’être informé du changement d’état d’un objet. Typiquement, un listener est une implémentation concrète du pattern Observer.
State : permet à un objet de base de modifier son comportement en fonction de son état. Un état correspond à une classe qui définit un comportement. (Par exemple, un lecteur vidéo avec les fonctionnalités “lecture”, “pause”, vidéo précédente/suivante”.
Strategy : permet, au moment d’exécuter un programme, de choisir parmi une liste de méthodes laquelle utiliser pour résoudre un problème, sans modifier le code initial qui utilise ces méthodes.
Template Method : permet de définir la structure globale d’un code et son déroulement (étapes) dans la méthode d’une classe de base. Le fonctionnement de certaines étapes peuvent ensuite être redéfinies dans des sous-classes, sans changer la structure du code initial.
Visitor : A l’aide d’un objet (le visiteur) et via une méthode commune, permet d’ajouter des fonctionnalités à des objets existants sans modifier le code de ces objets.
Conclusion
Voilà pour cette présentation et ce rapide aperçu des différents design patterns. Certains remarqueront que sans en connaitre le nom ou l’existence, certains patterns sont couramment utilisés dans de nombreux outils ou librairies, ou tout simplement dans votre propre code.
Retrouver sur ce site tous mes tutoriels pour prendre en main les design patterns comme un professionnel.