Les design pattern GoF - 2 éme partie


Dans cet article nous allons voir en détail l'objectif des designs pattern de GoF.

Les patterns de création

Les patterns de création ont pour vocation d’abstraire les mécanismes de création d’objets. Un système utilisant ces patterns devient indépendant de la façon dont les objets sont créés et, en particulier, des mécanismes d’instanciation des classes concrètes. Ces patterns encapsulent l’utilisation des classes concrètes et favorisent ainsi l’utilisation des interfaces dans les relations entre objets augmentant les capacités d’abstraction dans la conception globale du système.
Les 5 patterns de création sont
  • Factory Method
  • Abstract Factory
  • Builder
  •  Prototype
  • Singleton
Factory Method : a pour but d’introduire une méthode abstraite de création d’un objet en reportant aux sous-classes concrètes la création effective.
Utiliser ce pattern lorsque :
  • Une classe ne peut pas anticiper la classe des objets qu'elle doit créer.
Abstract Factory : a pour objectif la création d’objets regroupés en familles sans devoir connaître les classes concrètes destinées à la création de ces objets.
Utiliser ce pattern lorsque :
  • Le système devrait être indépendant de la façon dont ses produits sont créés, composés et représentés.
  • Le système doit être configuré avec l'une des multiples familles de produits.
Builder : permet de séparer la construction d’objets complexes de leur implantation de sorte qu’un client puisse créer ces objets complexes avec des implantations différentes
Utiliser ce pattern lorsque :
  • L'algorithme de création de l’objet doit être indépendant des parties qui composent l'objet et la manière dont ils sont assemblés. 
  • Le processus de construction de l’objet permet d’avoir différentes représentations de l'objet qui est construit.
Prototype : permet la création de nouveaux objets par duplication d’objets existants appelés prototypes qui disposent de la capacité de clonage.
Utiliser ce pattern lorsque :
  • L’instanciation d’un objet est coûteuse et il est plus simple d’avoir une copie d’un prototype et faire les modifications adéquates.
Singleton : permet de s’assurer qu’une classe ne possède qu’une seule instance et de fournir une méthode unique retournant cette instance.
Utiliser ce pattern lorsque :
  • Il doit y avoir exactement une instance d'une classe, et il doit être accessible aux autres objets à partir d'un point d'accès connu.
Les patterns de structuration 

L’objectif de ces patterns est de faciliter l’indépendance de l’interface d’un objet ou d’un ensemble d’objets vis-à-vis de son implantation. Dans le cas d’un ensemble d’objets, il s’agit aussi de rendre cette interface indépendante de la hiérarchie des classes de la composition des objets.

En fournissant les interfaces, les patterns de structuration encapsulent la composition des objets, augmentant le niveau d’abstraction du système à l’image des patterns de création qui encapsulent la création des objets. Les patterns de structuration mettent en avant les interfaces.

L’encapsulation de la composition est réalisé non pas en structurant l’objet lui-même mais en transférant cette structuration à un second objet. Celui-ci est intiment lié au premier objet. Ce transfert de structuration signifie que le premier objet détient l’interface vis-à-vis des clients et gère la relation avec le second objet qui lui gère la composition et n’a aucune interface avec les clients externes. Cette réalisation offre une autre propriété qui est la souplesse de la composition qui peut être modifiée dynamiquement. En effet, il est aisé de substituer un objet par un autre pourvu qu’il soit issu de la même classe ou qu’il respecte la même interface.

Les patterns de structuration apportent des solutions aux problèmes de structuration des données et des objets.

Les 7 patterns de structuration sont :
  • Adapter
  • Bridge
  • Composite
  • Decorator
  • Façade
  • Flyweight
  • Proxy
Adapter : l'objectif du pattern adapter est de convertir l’interface d’une classe existante en l’interface attendue par les des clients également existants afin qu’ils puissent travailler ensemble. Il s’agit de conférer à une classe existante une nouvelle interface pour répondre aux besoins des clients.
Utiliser ce pattern lorsque :
  • Vous voulez utiliser une classe existante, et son interface ne correspond pas à celle dont vous avez besoin.
Bridge : l'objectif de ce pattern est de séparer l’aspect d’implantation d’un objet de son aspect de représentation et d’interface. Ainsi d’une part l’implantation peut être totalement encapsulée et d’autre part l’implantation et la représentation peuvent évoluer indépendamment et sans que l’une exerce une contrainte sur l’autre.
Utiliser ce pattern lorsque :
  • Vous avez une prolifération de classes, une telle hiérarchie de classe montre qu'il est nécessaire de diviser un objet en deux parties.
Composite : le design pattern composite compose les objets dans les structures de type arbre ou arborescence. Il permet alors d’afficher une partie ou l’intégralité d’une hiérarchie.
Utilisez ce pattern lorsque :
  • Vous souhaitez représenter une partie de l'ensemble des hiérarchies d'objets.
Decorator : l'objedtif du pattern Decorator est d’ajouter dynamiquement des fonctionnalités supplémentaires à un objet.  Cet ajout de fonctionnalités ne modifie pas l’interface de l’objet et reste donc transparent vis-à-vis des clients. Le pattern Decorator constitue une alternative par rapport à la création d’une sous-classe pour enrichir un objet.
Utilisez ce pattern lorsque:
  • Vous voulez  ajouter des responsabilités à chacun des objets de façon dynamique et transparente.
Façade : le design pattern façade vise à simplifier l’accès à un ensemble d’objets formant un sous-système en fournissant à l’extérieur une interface unifiée, sous forme d’une ou de plusieurs classes, masquant la complexité liée à la manipulation de cet ensemble.
Utilisez ce pattern lorsque:
  • Vous voulez fournir une interface simple à un sous-système complexe.
  • Il existe de nombreuses dépendances entre les clients et la mise en œuvre d'une abstraction des classes permettra de découpler le sous-système de la part des clients et d'autres sous systèmes,
Flyweight : celui-ci désigne une technique de partage des ressources permettant la mise en oeuvre d'un grand nombre de petits objets. On parle dans ce cas d'objets de fine granularité.

Proxy : le design pattern proxy masque la complexité d’utilisation d’un objet en présentant une interface simplifiée. Il encapsule tout ou partie du protocole d’accès à l’objet dont il prend en charge les aspects techniques. Idéalement, un proxy se présente comme un POJO (Plain Old Java Object), c’est-à-dire un objet Java élémentaire, permettant un accès simplifié à un composant.

Les patterns de comportement 

L’objectif de ces patterns est de fournir des solutions pour distribuer les traitements et les algorithmes entre les objets. Ces patterns organisent les objets ainsi que leurs interactions en spécifiant les flux de contrôle et de traitement au sein d’un système d’objets.

Les 11 patterns de comportement sont :
  • Chain of responsibility  
  • Command  
  • Iterator 
  • Mediator 
  • Memento 
  • Observer 
  • State 
  • Strategy 
  • Template Method 
  • Visitor
Chain of Responsibility : construit une chaîne d’objets telle que si un objet de la chaîne ne peut pas répondre à une requête, il puisse la transmettre à son successeur et ainsi de suite jusqu’à ce que l’un des objets de chaîne y réponde.
Utilisez ce pattern lorsque :
  • Plus d'un objet peut traiter une demande et le gestionnaire n'est pas connu à priori.
  • Vous souhaitez émettre une demande de l'un de plusieurs objets sans préciser explicitement le récepteur.
Command : le principal objectif de ce Design Pattern est d’encapsuler une requête sous forme d’objet.
Utilisez ce pattern lorsque:
  • Vous voulez paramétrer des objets pour réaliser certaines actions avec différentes requêtes. 
  • Pour spécifier, mettre en file, et exécuter des requêtes à des moments différents.
  • Pour implémenter des opérations réversibles. 
  • Pour structurer un système à l’aide d’opérations de haut niveau construites à partir d’opérations primitives.
Iterator : ce pattern est très utilisé et permet d’accéder à des éléments d’un agrégat séquentiellement. Il a pour but premier de donner un moyen de parcourir et d’accéder aux éléments sans pour autant exposer sa structure interne. Il peut également avoir différents moyens de lister le contenu (ordre croissant/décroissant, insertion…) et permettre (si on le souhaite) d’accéder simultanément à la liste avec différents moyens (croissant et décroissant en même temps par exemple).

Mediator : a pour but de construire un objet dont la vocation est la gestion et le contrôle des interactions dans un ensemble d’objets sans que ses éléments doivent se connaître mutuellement.
Utilisez ce pattern lorsque:
  • Un jeu d'objets communique de façons bien définies mais complexes. Les interdépendances résultantes sont peu structurées et difficiles de comprendre. 
  • La réutilisation d'un objet est difficile parce qu'il attribue à et communique avec beaucoup d'autres objets.
Memento : sans violer l'encapsulation, capture et externalise un objet interne de l'état de sorte que l'objet peut être remis dans cet état plus tard.
Utiliser ce pattern lorsque :
  • Une partie de l'état d'un objet doit être sauvgardée de sorte qu'il puisse être rétabli à cette état plus tard.
Observer : définir une relation 1-n entre les objets de sorte que quand un objet change d’état, tous les objets en relation notifiés et mis à jour automatiquement.
Utiliser ce pattern lorsque :
  • Une modification d'un objet nécessite la modification d'autres, et on ne sait pas combien d'objets doivent être Changé.
State : permet, lorsqu’un objet est altéré, de changer son comportement. Le changement d’état peut parfois poser des problèmes dans leurs gestions, le Pattern State permet de pallier à ce problème de manière simple et rapide.
Utiliser ce pattern lorsque :
  • Le comportement d'un objet dépend de son état, et il doit changer d'attitude à l'exécution, selon cet état.
Strategy : définir une famille d'algorithmes, encapsulés les unes dans les autres, et de les rendre interchangeables. Stratégie permet à l'algorithme de varier indépendamment de la part des clients qui l'utilisent.
Utiliser ce pattern lorsque :
  • De nombreux classes ne diffèrent que par leur comportement. Stratégies de fournir un moyen de configurer une classe  avec l'un des nombreux comportements.
  • Vous devez de différentes variantes d'un algorithme. Par exemple, vous pouvez définir des algorithmes reflétant différentes espace / temps des compromis. Les stratégies peuvent être utilisés lorsque ces variantes sont mises en œuvre comme une hiérarchie de classe d’algorithmes.
  • La classe définit de nombreux comportements, et ceux-ci apparaissent sous forme de conditions. Plutôt que de nombreuses conditions déplacer ces conditions  à leurs propres succursales stratégie classe.
Template Method : définir le squelette d'un algorithme dans une opération,  le pattern Template Method permet de redéfinir certaines étapes d'un algorithme sans modifier la structure de l'algorithme.
Utiliser ce pattern lorsque :
  • A mettre en œuvre les parties invariantes d'un algorithme une fois et laisser le soin à des sous-classes de mettre en œuvre le comportement qui peut varier.
  •   Lorsque le comportement commun entre les sous-classes doivent être pris et localisée dans une  classe commune afin d’éviter la duplication du code.
Visitor : représentent une opération doit être effectuée sur les éléments de la structure d'un objet. Visiteur vous permet de définir une nouvelle  opération sans changer les classes des éléments sur lesquels il opère.
Utiliser ce pattern lorsque :
  • La structure d’un objet contient de nombreuses classes d'objets  avec des interfaces différentes, et que vous voulez effectuer  des opérations sur ces objets qui dépendent de leurs classes concrètes.
  • Les classes définissent la structure de l'objet sont  rarement changées, mais vous avez souvent besoin de définir de nouvelles opérations sur la structure.
 Conclusion

Dans cette article nous avons vu les objectifs et quelques cas d'utilisation des designs pattern GoF. Je vous laisse donc voir le diagramme de classe et comment implémenter chaque design pattern.

Référence :                                                                                                                                    
Les design Patterns : les 23 modèles de conception - Laurent Debrauwer                   
Core J2EE Patterns - Best Practices and Design Strategies

Aucun commentaire: