0% ont trouvé ce document utile (0 vote)
45 vues4 pages

Design Patterns de Structure en Programmation

Ce document décrit plusieurs patrons de conception structurels comme l'adaptateur et le décorateur. Il explique leur définition et donne des exemples concrets de leur utilisation, comme la conversion de formats de données avec un adaptateur ou l'ajout dynamique de fonctionnalités avec un décorateur.

Transféré par

ta lou
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
45 vues4 pages

Design Patterns de Structure en Programmation

Ce document décrit plusieurs patrons de conception structurels comme l'adaptateur et le décorateur. Il explique leur définition et donne des exemples concrets de leur utilisation, comme la conversion de formats de données avec un adaptateur ou l'ajout dynamique de fonctionnalités avec un décorateur.

Transféré par

ta lou
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

ORGANISEZ VOS CLASSES AVEC LES DESIGN PATTERNS DE STRUCTURE

I. DEFINITION
Les patrons structurels vous guident pour assembler des objets et des classes en de plus grandes
structures tout en gardant celles-ci flexibles et efficaces. Par exemple, vous allez dans un
supermarché, après sélection de vos articles, vous vous rendez à la caisse et vous payez. Il s’agit
là d’un exemple de pattern de structure où une interface simple masque une grande complexité.
En tant que Client du magasin, il n’est pas important pour vous de savoir comment les produits
ont été commandés, comment ils ont été livrés ou comment ils ont été disposés en rayon.

II. PATTERN ADAPTATEUR


Un exemple concret d’utilisation du pattern adaptateur est le suivant :
Mon ordinateur dispose d'un connecteur HDMI. Mais j’utilise un vieil écran, qui a seulement un
connecteur VGA. Pour afficher le contenu de l’écran de mon ordinateur sur le vieil écran, j'ai
besoin d'un adaptateur pour convertir les signaux !
En d’autres termes, le pattern adaptateur permet de faire collaborer des objets ayant des
interfaces normalement incompatibles.

a. Problème

Imaginez que vous êtes en train de créer une application de surveillance du marché boursier.
L’application télécharge des données de la bourse depuis diverses sources au format XML et
affiche ensuite de jolis graphiques et diagrammes destinés à l’utilisateur. Après un certain temps,
vous décidez d’améliorer l’application en intégrant une librairie d’analyse externe. Mais il y a un
hic ! Cette librairie ne fonctionne qu’avec des données au format JSON.

Figure 1: Schéma de communication d'applications hétérogènes

b. Solution populaire (mauvaise solution)

Vous pourriez modifier la librairie afin qu’elle accepte du XML, mais vous risquez de faire planter
d’autres parties de code qui utilisent déjà cette librairie. Ou alors, vous n’avez tout simplement
pas accès au code source de la librairie, rendant la tâche impossible.
c. Solution avec le pattern adaptateur

Vous créez un adaptateur. C’est un objet spécial qui convertit l’interface d’un objet afin qu’un autre
objet puisse le comprendre.
Un adaptateur encapsule un des objets afin de masquer la complexité de la conversion, exécutée
en arrière-plan. L’objet encapsulé n’a pas conscience de ce que fait l’adaptateur. Par exemple,
vous pouvez encapsuler un objet qui calcule en mètres et en kilomètres avec un adaptateur qui
effectue la conversion de toutes les données en unités impériales comme les pieds et les milles.
Dans le cas de notre problème, on propose la solution suivante :

Figure 2: Schéma de communication d'applications hétérogènes avec le pattern adaptateur

Pour résoudre le problème des formats incompatibles, vous pouvez créer des adaptateurs XML
vers JSON pour chaque classe de la librairie que notre code veut utiliser. Vous n’avez plus qu’à
ajuster votre code pour communiquer avec la librairie à l’aide de ces adaptateurs. Lorsqu’un
adaptateur reçoit un appel, il convertit les données XML en une structure JSON. Il renvoie ensuite
l’appel à la méthode appropriée dans un objet d’analyse encapsulé.

d. Mise en œuvre

Dans notre jeu de cartes, imaginons que nous ayons créé une interface PlayableCard et que notre
PlayingCard l'ait implémentée :

1. interface PlayableCard {
2. void flip();
3. };
4.
5. class PlayingCard implements PlayableCard {
6. bool faceUp;
7. void flip () {
8. faceUp = !faceUp;
9. }
10. };
Mais un autre développeur de l’équipe a créé une classe CoolCard qui a l’air mieux que notre
implémentation. Nous décidons donc d’utiliser celle-ci à la place :

1. class CoolCard {
2. void turnOver() {
3. // implémentation cool ici
4. }
5. };
Si nous utilisions cette nouvelle carte, chaque endroit faisant appel à notre opération flip() devrait
être remplacé par turnOver(). Cela n'a rien de très difficile dans notre jeu de cartes, mais imaginez
cela sur un projet de plus grande ampleur ! Utilisons à la place un adaptateur qui ressemble à
une PlayableCard, mais qui se comporte comme une CoolCard :

1. class PlayingCardAdapter implements PlayableCard {


2. CoolCard thisCard;
3. void flip() {
4. [Link]();
5. }
6. };
Avec ce PlayingCardAdapter , nous n'avons pas besoin de modifier tous les appels à flip() ! Nous
devons cependant utiliser des objets PlayingCardAdapter au lieu d'objets PlayingCard. Mais
souvenez-vous, nous disposons d'une Factory qui fait tout cela ! La Factory est donc la seule partie
du code qui doit être informée de l'ajout du nouveau concept CoolCard.

III. PATTERN DECORATEUR


Le pattern Décorateur permet d’affecter dynamiquement de nouveaux comportements à des
objets en les plaçant dans des emballeurs (Wrapper) qui implémentent ces comportements.

a. A quel moment utiliser le pattern décorateur

Très souvent, lorsque l’on souhaite ajouter des fonctionnalités à une classe, on pense
héritage – et c’est un bon réflexe !
Mais, très souvent également, cette solution n’est pas réellement adaptée : on peut
souhaiter ajouter plusieurs fonctionnalités à la même classe de manière dynamique (à
l’exécution) et non pas à l’écriture du programme (ajout de fonctionnalité statique). En
choisissant les nouvelles fonctionnalités pour chaque instance et non pour la classe.
C’est dans ce cas qu’il est pertinent de faire appel au design pattern Décorateur.

L’avantage du Design Pattern Décorateur : l’ajout simplifié des nouvelles fonctionnalités


qu’on souhaite intégrer à une classe, et cela de façon dynamique sans impacter les classes
qui l’utilisent ou en héritent.

b. Exemple pratique pour la mise en œuvre du Pattern Decorateur

Prenons le cas d’un logiciel qui rend les noms des personnes accessibles via la classe
abstraite « employee ». Cependant, la première lettre des noms retrouvés est toujours en
minuscule. Comme une adaptation ultérieure est impossible, la classe de décorateur «
EmployeeDecorator » est implémentée, qui fonctionne via la même interface et permet
également l’appel de la méthode getName(). En outre, le décorateur reçoit une logique
qui garantit que la première lettre est correctement mise en majuscule. L’exemple de
code approprié ressemble à ceci :
1. public class EmployeeDecorator implements Person {
2. private Employee employee;
3. public EmployeeDecorator(Employee employee){
4. [Link] = employee;
5. }
6. public String getName(){
7. // appelle la méthode de la classe d’employés
8. String name = [Link]();
9. // Veillez à ce que la première lettre soit en majuscule ici
10. name = [Link]([Link](0))
11. + [Link](1, [Link]());
12. return name;
13. }
14. }

Vous aimerez peut-être aussi