Participer au site avec un Tip
Rechercher
 

Améliorations / Corrections

Vous avez des améliorations (ou des corrections) à proposer pour ce document : je vous remerçie par avance de m'en faire part, cela m'aide à améliorer le site.

Emplacement :

Description des améliorations :

Qu'est-ce qu'un « Design Pattern » ?

Utilisation de l'API SLF4J Le design pattern « Singleton »



Accès rapide :
Introduction
De quoi parle-t-on ?
Comment représente-t-on un Design pattern ?
Les différentes catégories de Design Patterns
Les design patterns de construction - Creational design patterns
Les design patterns structuraux - Structural design patterns
Les design patterns comportementaux - Behavioral design patterns

Introduction

le terme de « Design Pattern » est bien entendu d'origine anglo-saxonne. En français, on devrait plutôt parler de « patron de conception » ou de « motif de conception ». Pour autant, comme la majorité des informaticiens utilisant la terminologie anglo-saxonne, je préfère continuer à parler de « Design Pattern » dans ce tutoriel Java.

De quoi parle-t-on ?

Un design pattern est une solution éprouvée pour répondre à une problématique récurrente de la programmation informatique.

A l'origine de ces concepts se cachent quatre grands informaticiens : Erick Gamma, Richard Helm, Ralph Johnson et John Vlissides. En analysant un grand nombre de programmes informatiques et de différentes natures, ils sont arrivés à une conclusion : il y a des problèmes récurrents que l'on rencontre dans de multiples programmes. En réponse à ces problématiques en retrouve souvent des modèles de code qui s'avèrent être efficaces sur de nombreux points de vue (maintenabilité, performances...). Du coup, pourquoi réinventer la roue à chaque fois ? Ne serait-ce pas mieux de connaître par coeur chaque problématique ainsi que le modèle de code associé qui répond à cette problématique ? Ainsi on pourrait gagner du temps et on éviterait de réfléchir à des solutions qui, de toutes façons, seraient moins bonnes.

ces quatre personnes, aussi connus sous le terme de « Gang Of Four » (ou plus simplement GOF), ont rédigé un ouvrage aujourd'hui considéré comme étant la bible en la matière : « Design Patterns: Elements of Reusable Object-Oriented Software » édité chez Addison-Wesley (ISBN 978-0-201-63361-0).
Design Patterns: Elements of Reusable Object-Oriented Software - Addison-Wesley

Pour faire une analogie, on pourrait parler du jeu des échecs. Personnellement, c'est un jeu qui m'amuse, mais j'ai appris sur le tas avec mon père. Je pensais avoir un bon niveau, jusqu'au jour ou j'ai joué avec quelqu'un qui a appris dans un club d'échec. Et là... ce fut le drame. Alors que je passais de longues minutes à analyser tous les coups possibles et les meilleures alternatives, mon adversaire connaissait déjà par coeur la configuration du jeu et savais pertinemment quel coup jouer. Pire encore, la plupart du temps, il savait avant moi ou j'allais jouer. Du coup, il n'a pas fait d'erreur et m'a atomisé.

Hé bien, pour produire du code, on peut avoir une démanche similaire. Dès que l'on reconnaît une problématique, on ne réfléchit pas et on applique le modèle de conception (le design pattern) que l'on connaît par coeur pour répondre à cette problématique. Bien entendu, faut-t-il les avoir appris par coeur.

A l'origine (1994), le gang des quatre (GOF) ont défini 23 patterns. Mais par la suite, d'autres personnes, convaincu par la démarche, en ont proposés d'autres. Aujourd'hui, un bon développeur peu être amené à connaître une cinquantaine de patterns.

le plus compliqué, quand vous souhaitez mettre en oeuvre les design patterns, c'est de reconnaître les problématiques dans le programme à développer. Une fois qu'on les a identifiées, il ne reste plus qu'à dérouler les design patterns associés.
il est aussi à noter que les diverses API Java sont fortement basées sur ces design patterns. Peut-être en reconnaîtrez-vous certains.
en complément, vous pouvez aussi consulter la page Wikipedia suivante : Software design pattern

Comment représente-t-on un Design pattern ?

Littéralement, on peut traduire Design Pattern en motif de conception. On parle donc de ce sujet durant les phases de conception du logiciel. C'est pour cela que la plupart du temps, on représente un design pattern via le formalisme UML.

UML (Unified Modeling Language) est un formalisme graphique permettant de représenter tous les aspects de la conception d'un logiciel et ce depuis la phase d'expression des besoins jusqu'à la représentation du déploiement du logiciel final. Dans les faits, il existe un grand nombre de types de diagrammes UML, mais le plus connu reste le diagramme de classes. C'est ce dernier que nous allons exploiter pour détailler quelques design patterns importants.

Très souvent, quand on parle de design patterns, les développeurs ont en têtes les lignes de codes équivalentes au pattern qu'ils considèrent. Mais c'est une erreur : un design pattern est indépendant d'un quelconque langage de programmation et ils devraient plutôt avoir en tête la conception UML. Pour ce qui est du code, il serait plus logique de parler d'« implementation patterns », d'autant que selon les langages de programmation considérés, un même pattern peut se mettre en oeuvre avec quelques légères variations.

Les différentes catégories de Design Patterns

Tous ces patterns ont été regroupés dans différentes catégories. Les membres du GOF avaient initialement proposé trois catégories. Elles sont toujours d'actualité à ce jour, bien qu'on puisse en envisager d'autres.

Les design patterns de construction - Creational design patterns

Nom du pattern GOF Description
Abstract factory
(Fabrique abstraite)
Oui Permet la création d'un ensemble d'objets cohérents entre eux, selon un critère donné, sans devoir connaître les classes concrètes à instancier.
Builder
(Monteur)
Oui Permet de séparer la construction d'un objet complexe de sa représentation, afin de construire diverses représentations via un même processus.
Factory method
(Méthode de fabrique)
Oui Permet de créer une instance à partir d'une classe dérivée d'un type abstrait, selon un critère donné et en vous évitant de systématiquement d'avoir à évaluer le critère de choix. La classe exacte utilisée pour produire l'objet n'est donc pas connue par l'appelant.
Multiton Non Permet de gérer un ensemble d'instances nommées et d'en garantir l'unicité pour un nom donné. Le pattern prévoit un point d'accès unique pour retrouver une instance par son nom.
Object pool
(Pool d'objets)
Non Permet de maintenir en mémoire un ensemble de ressources pouvant être partagées par différents traitements. Si le temps d'acquisition d'une ressource est relativement long, le fait de les conserver et de les repasser à qui en a besoin, peut être un facteur d'optimisation. Par exemple, un pool de threads ou un pool de connexions à une base de données.
Prototype Oui Permet de produire un objet par duplication d'un autre objet que l'on peut ensuite faire évoluer. Cela est utile quand le processus de création nominal prend beaucoup de temps.
Singleton Oui Permet de s'assurer qu'une classe ne puisse produire qu'une seule et unique instance. Le singleton est certainement le plus simple des design patterns : c'est pour cela qu'il est souvent considéré comme le « Hello World » des design patterns.

Les design patterns structuraux - Structural design patterns

Nom du pattern GOF Description
Adapter
(Adpateur)
Oui Permet d'adapter l'interface d'un composant logiciel existant à celle utilisée par un client, lui aussi déjà existant. Cela est requis qu'en les deux participants (composant et client) non pas été initialement prévu pour travailler ensemble.
Bridge
(Pont)
Oui Permet de séparer une implémentation interne de sa représentation (son interface).
Composite Oui Permet d'agréger des éléments dans un conteneur en garantissant que le conteneur puisse cascader certaines de ses actions sur tous les éléments qu'il contient. Par exemple, imaginez un atelier de développement qui cascade les appels de son cycle de vie aux plugins qu'il contient (c'est notamment le cas de l'atelier Eclipse et de ses plugins).
Decorator
(Décorateur)
Oui Permet d'ajouter dynamiquement des fonctionnalités additionnelles à un objet. Ce pattern peut donc être vue comme une alternative à l'héritage.
Facade
(Façade)
Oui Permet de fournir une interface simplifiée (ou de plus haut niveau d'abstraction) à un composant bien plus complexe (ou de bas niveau d'abstraction).
Flyweight
(Poids-mouche)
Oui Permet de développer une application utilisant un très grand nombre d'instances qui partagent souvent des caractéristiques communes. Afin de ne pas trop saturer la mémoire, il est conseillé d'utiliser ce pattern. L'exemple typique, c'est un traitement de texte : il permet de saisir un très grand nombre de caractères et pour chacun d'eux, il existe plein de caractéristiques (taille, police, couleurs...). Or, tous les caractères d'un même paragraphe ont souvent les mêmes caractéristiques. De manière très naïve, dans un traitement de texte le Flyweight correspond au code de gestion des styles graphiques de ces caractères.
Proxy Oui Permet d'intercepter les appels à un objet pour y injecter des traitements particuliers. Ce pattern est essentiel en informatique et on le retrouve très fréquemment pour répondre à de multiples besoins.

Les design patterns comportementaux - Behavioral design patterns

Nom du pattern GOF Description
Chain of responsibility
(Chaîne de responsabilité)
Oui Permet de construire une chaîne d'objets (une liste chaînée) de telle sorte que si un objet de la chaîne ne peut pas traiter la demande, il la transmet à l'objet suivant et ainsi de suite jusqu'à ce que l'un des objets de chaîne puisse la gérer.
Command
(Commande)
Oui Permet d'encapsuler une demande sous forme d'objet. Notamment très utile pour les API graphiques telle que Swing (et sa notion d'action).
Interpreter
(Interpréteur)
Oui Permet de coder l'interprétation de la grammaire d'un langage simple (pouvant être transformé sous forme d'arbres).
Iterator
(Itérateur)
Oui Permet de parcourir séquentiellement les éléments d'une collection sans forcément exposer la structure interne de la collection. L'API de collection Java (java.util.List, java.util.Iterator...) met notamment en oeuvre ce pattern.
Mediator
(Médiateur)
Oui Permet, quand votre programme met en oeuvre en grand nombre d'objets interconnectés en eux et qui doivent communiquer ensemble, de définir un point de communication unique (le médiateur).
Memento Oui Permet de sauver ou de restaurer l'état d'un objet sans violer le principe d'encapsulation.
Observer or
Publish/Subscribe
(Observeur)
Oui Permet de définir une relation 1-n entre les objets de telle sorte que si un objet change d'état, alors toutes les instances en relation avec cet objet pourront être notifiées du changement. En Java, le principe de listener (pour la gestion des événements) respecte ce design pattern.
State
(Etat)
Oui Permet, lorsqu'un objet change d'état, de modifier son comportement.
Strategy
(Stratégie)
Oui Permet de pouvoir implémenter, de différentes manières, un traitement et de pourvoir choisir automatiquement la bonne implémentation. Dit autrement, ce pattern explicite le principe de « liaison dynamique de méthode ».
Template method
(Méthode template)
Oui Permet de définir la structure générale d'un algorithme, au niveau d'une classe mère, en déléguant certains calculs à ses sous-classes. En conséquence, il est possible de charger certaines étapes d'un traitement sans en changer son algorithmique.
Visitor
(Visiteur)
Oui Permet de définir une nouvelle opération sans modifier les classes des instances sur lesquels elle s'exécute.


Utilisation de l'API SLF4J Le design pattern « Singleton »