Le modèle de conception du patron de décorateur est utilisé pour modifier la fonctionnalité d’un objet à l’exécution. En même temps, les autres instances de la même classe ne seront pas affectées par cela, de sorte que chaque objet individuel obtient le comportement modifié. Le modèle de conception du décorateur est l’un des modèles de conception structurels (tels que le patron d’adaptateur, le patron de pont, le patron composite) et utilise des classes abstraites ou une interface avec composition pour implémenter.
Modèle de conception du décorateur
Nous utilisons l’héritage ou la composition pour étendre le comportement d’un objet, mais cela se fait à la compilation et s’applique à toutes les instances de la classe. Nous ne pouvons pas ajouter de nouvelles fonctionnalités ou supprimer un comportement existant à l’exécution – c’est là que le modèle Décorateur entre en jeu. Supposons que nous voulions implémenter différents types de voitures – nous pouvons créer une interface Car pour définir la méthode d’assemblage, puis nous pouvons avoir une voiture de base, que nous pouvons ensuite étendre en voiture de sport et en voiture de luxe. La hiérarchie d’implémentation ressemblera à l’image ci-dessous. Mais si nous voulons obtenir une voiture à l’exécution qui a à la fois les fonctionnalités d’une voiture de sport et d’une voiture de luxe, alors l’implémentation devient complexe et si nous voulons spécifier quelles fonctionnalités doivent être ajoutées en premier, cela devient encore plus complexe. Maintenant, imaginez si nous avions dix types de voitures différents, la logique d’implémentation en utilisant l’héritage et la composition serait impossible à gérer. Pour résoudre ce type de situation de programmation, nous appliquons le modèle Décorateur en Java. Nous avons besoin des types suivants pour implémenter le modèle de conception du décorateur.
-
Interface de composant – L’interface ou la classe abstraite définissant les méthodes qui seront mises en œuvre. Dans notre cas,
Car
sera l’interface du composant.package com.journaldev.design.decorator; public interface Car { public void assemble(); }
-
Implémentation de composant – L’implémentation de base de l’interface de composant. Nous pouvons avoir la classe
BasicCar
comme notre implémentation de composant.package com.journaldev.design.decorator; public class BasicCar implements Car { @Override public void assemble() { System.out.print("Voiture de base."); } }
-
Décorateur – La classe Décorateur implémente l’interface composant et elle a une relation HAS-A avec l’interface composant. La variable composant doit être accessible aux classes de décorateur enfant, nous rendrons donc cette variable protégée.
package com.journaldev.design.decorator; public class CarDecorator implements Car { protected Car car; public CarDecorator(Car c){ this.car=c; } @Override public void assemble() { this.car.assemble(); } }
-
Décorateurs concrets – Étendent la fonctionnalité de base du décorateur et modifient le comportement du composant en conséquence. Nous pouvons avoir des classes de décorateur concrets comme
LuxuryCar
etSportsCar
.package com.journaldev.design.decorator; public class SportsCar extends CarDecorator { public SportsCar(Car c) { super(c); } @Override public void assemble(){ super.assemble(); System.out.print(" Ajout des fonctionnalités d'une voiture de sport."); } }
package com.journaldev.design.decorator; public class LuxuryCar extends CarDecorator { public LuxuryCar(Car c) { super(c); } @Override public void assemble(){ super.assemble(); System.out.print(" Ajout des fonctionnalités d'une voiture de luxe."); } }
Patron de conception Décorateur – Diagramme de classe
Programme de test du patron de conception Décorateur
package com.journaldev.design.test;
import com.journaldev.design.decorator.BasicCar;
import com.journaldev.design.decorator.Car;
import com.journaldev.design.decorator.LuxuryCar;
import com.journaldev.design.decorator.SportsCar;
public class DecoratorPatternTest {
public static void main(String[] args) {
Car sportsCar = new SportsCar(new BasicCar());
sportsCar.assemble();
System.out.println("\n*****");
Car sportsLuxuryCar = new SportsCar(new LuxuryCar(new BasicCar()));
sportsLuxuryCar.assemble();
}
}
Notez que le programme client peut créer différents types d’objets à l’exécution et spécifier l’ordre d’exécution également. La sortie du programme de test ci-dessus est :
Basic Car. Adding features of Sports Car.
*****
Basic Car. Adding features of Luxury Car. Adding features of Sports Car.
Patron de conception Décorateur – Points importants
- Le patron de conception décorateur est utile pour fournir des capacités de modification à l’exécution et donc plus de flexibilité. Il est facile à entretenir et à étendre lorsque le nombre de choix est plus grand.
- L’inconvénient du patron de conception décorateur est qu’il utilise beaucoup d’objets de types similaires (décorateurs).
- Le modèle de décorateur est largement utilisé dans les classes Java IO, telles que FileReader, BufferedReader, etc.
Source:
https://www.digitalocean.com/community/tutorials/decorator-design-pattern-in-java-example