1 - Introduction
En premier lieu, les design patterns sont des modèles de conception répondant à des problématiques spécifiques dans la programmation orientée objet. Ils permettent aussi d'apporter des solutions efficaces, éprouvées par des développeurs experts dans le domaine et appliquées à des problèmes récurrents. Pourquoi réfléchir de zéro à un problème à chaque fois alors qu'il y a une solution existante à ce dernier ? De plus, ils facilitent la lecture du code par un autre développeur.
L’ouvrage qui a permis leur démocratisation est Design Patterns : Elements of reusable software, co-écrit par le Gang Of Four, composé des auteurs Gamma, Helm, Johnson et Vlissides. En effet, dans cet ouvrage, ils décrivent plus d'une vingtaine de design patterns qui sont classés sur trois catégories :
D'abord, les modèles de création "Creational design patterns"
Ensuite, les modèles de structuration "Structural design patterns"
Enfin, les modèles de comportement "Behavioral design patterns"
Cet article va donc aborder une sélection de design patterns les plus connus dans chacune de ces catégories pour mieux les appréhender.
2 - Design patterns : les modèles de création « Creational patterns »
Les modèles de création, qui concernent l’instanciation et la configuration des classes et des objets, font appelles à deux concepts de la POO qui sont l’héritage et la délégation.
2.1 Singleton pattern
2.1.1 Problématique
Très souvent cité en entretien, le singleton pattern est un des modèles de design patterns le plus connu. Il répond en effet au besoin de n’avoir qu’une seule instance d’une classe et que cette dernière soit accessible dans toute l'application.
2.1.2 Exemple
Plus précisement, exemple basique du Singleton avec l’instance statique et la méthode statique pour la retourner.
2.1.2.1 Schéma
schéma de Singleton
2.1.2.2 Code
2.2 Builder pattern
2.2.1 Problématique
La construction d’une classe contenant plusieurs champs peut en effet être lourde à implémenter, surtout lorsque l’alimentation d’un certain champ dépend d’une logique métier complexe. Le Builder pattern consiste à déplacer cette logique de construction hors de la classe concernée afin de l’alléger et pour rendre plus modulable la construction de l’objet.
2.2.2 Exemple
Un produit avec des attributs qui est construit par une classe Builder.
2.2.2.1 Schéma
schéma de Builder pattern
2.2.2.2 Code
2.3 Factory Method Pattern
2.3.1 Problématique
Dans les design patterns, le factory method pattern permet de créer des objets d’une même famille sans avoir à spécifier leur classe. Ce rôle est délégué à la Factory qui saura, à partir de certains paramètres, créer les objets de la bonne classe sans exposer la logique de leur création. De fait, c’est un pattern souvent utilisé dans les Frameworks et les librairies qui fournissent le contrat d’utilisation aux applications clientes.
2.3.2 Exemple
Deux produits (TV, Radio) qui héritent d’une interface commune et qui sont construits par une classe Factory selon le type de produit.
2.3.2.1 Schéma
schéma de Factory Method Pattern
2.3.2.2 Code
3 - Design patterns : les modèles de structuration "Structural patterns"
3.1 Adapter
3.1.1 Problématique
Ce pattern permet, pour un client qui ne pourrait pas appeler directement les fonctionnalités d’un programme, d’utiliser une interface adaptée à ce dernier.
3.1.2 Exemple
Un adaptateur HDMI vers VGA où la classe « Adapter » implémente cette adaptation.
3.1.2.1 Schéma
schéma de Structural pattern
3.1.2.2 Code
3.2 Bridge
3.2.1 Problématique
Le pattern du bridge permet de séparer la modélisation d’un problème à résoudre de son implémentation. Le problème est ainsi modélisé par une classe abstraite et une ou plusieurs classes représentent les implémentations possibles de cette problématique. Les implémentations peuvent donc évoluer et être changées en fonction des besoins sans avoir à modifier la modélisation du problème à résoudre.
3.2.2 Exemple
Un opérateur qui peut effectuer toutes les opérations qui implémentent l’interface « IOperation » en appelant la méthode « doOperation »
3.2.2.1 Schéma
schéma de Bridge
3.2.2.2 Code
3.3 Composite
3.3.1 Problématique
Le pattern du composite représente les objets de manière hiérarchisée sous forme d’une structure d’arbre et ces objets peuvent eux-mêmes être composés par d’autres objets afin qu’ils puissent être traités de manière uniforme.
3.3.2 Exemple
Un employé qui peut gérer zéro ou plusieurs employées.
3.3.2.1 Schéma
schéma de composite
3.3.2.2 Code
4 - Design patterns : les modèles de comportement "Behavioral patterns"
4.1 Observer
4.1.1 Problématique
Le pattern Observer répond au besoin des clients de suivre le changement d’état d’un objet afin de se mettre à jour. En effet dans ce pattern, un «Subject » est observé par des « Observers » qui s’enregistrent auprès de lui et qui seront notifiés de toutes les modifications.
4.1.2 Exemple
Un article « Subject » qui est suivi par plusieurs lecteurs « Observers » où lorsqu'il est modifié, les lecteurs seront alors notifiés.
4.1.2.1 Schéma
Schéma de Behavioral pattern
4.1.2.2 Code
4.2 State
4.2.1 Problématique
Là-dessus, l'’état d’un objet est déterminé par le changement de valeurs de ces attributs. Le State pattern permet donc à l’objet de changer son comportement quand un changement survient sur son statut interne.
4.2.2 Exemple
Un moteur qui peut être démarré ou à l’arrêt.
4.2.2.1 Schéma
schéma de State
4.2.2.2 Code
4.3 Strategy
4.3.1 Problématique
Un objet client a en effet besoin de choisir dynamiquement un algorithme adapté à la problématique qu’il traite. Alors le strategy pattern permet d’encapsuler chaque algorithme dans une classe d’implémentation et de pouvoir utiliser la plus adaptée pour résoudre un problème.
4.3.2 Exemple
Un exemple de jeu où il y a plusieurs stratégies notamment celle d’attaque ou de défense.
4.3.2.1 Schéma
schéma de Strategy
4.3.2.2 Code
Pour conclure sur le sujet des design patterns, il n’y a donc plus que le pattern du Singleton à citer dans un prochain entretien. Essentiellement, la manière la plus efficace pour les retenir c’est la pratique dès que l’occasion se présente, n’hésitez pas à les utiliser !
Poursuivez votre lecture sur nos autres articles autour de Java !