Modèle de décorateur


Le Decorator Pattern permet d'ajouter de nouvelles fonctionnalités à un objet existant sans changer sa structure. Ce type de modèle de conception est un modèle structurel, qui agit comme un wrapper autour d’une classe existante.

Ce modèle crée une classe de décoration pour envelopper la classe d'origine et fournir des fonctionnalités supplémentaires tout en conservant l'intégrité de la signature de la méthode de classe.

Nous démontrons l'utilisation du motif décorateur à travers l'exemple suivant. Parmi eux, nous décorerons une forme avec différentes couleurs sans changer la classe de forme.

Introduction

Intention : Ajouter dynamiquement des responsabilités supplémentaires à un objet. En termes d'ajout de fonctionnalités, le modèle de décorateur est plus flexible que la génération de sous-classes.

Solution principale : Généralement, nous utilisons souvent l'héritage pour étendre une classe. Puisque l'héritage introduit des fonctionnalités statiques dans la classe, et à mesure que les fonctions d'extension augmentent, la sous-classe sera considérablement étendue.

Quand l'utiliser : Étendre une classe sans ajouter de nombreuses sous-classes.

Comment résoudre : Divisez les responsabilités fonctionnelles spécifiques et héritez du modèle du décorateur.

Code clé : 1. La classe Component joue un rôle abstrait et ne doit pas être implémentée concrètement. 2. Modifiez la classe pour référencer et hériter de la classe Component, et étendez spécifiquement la classe pour remplacer la méthode de la classe parent.

Exemples d'application : 1. Sun Wukong a 72 transformations lorsqu'il devient un « temple », il est toujours fondamentalement un singe, mais il a la fonction d'un temple. 2. Un tableau peut être accroché au mur, qu'il ait ou non un cadre, mais il a généralement un cadre et le cadre est en fait accroché au mur. Avant d'être accroché au mur, le tableau peut être vitré et encadré ; le tableau, le verre et le cadre forment alors un seul objet.

Avantages : La classe décoration et la classe décorée peuvent se développer indépendamment et ne seront pas couplées l'une à l'autre. Le mode décoration est un mode alternatif à l'héritage. Le mode décoration peut étendre dynamiquement le mode décoration. fonctions d’une classe d’implémentation.

Inconvénients : La décoration multicouche est plus compliquée.

Scénarios d'utilisation : 1. Étendre les fonctionnalités d'une classe. 2. Ajoutez dynamiquement des fonctions et annulez-les dynamiquement.

Remarque : peut remplacer l'héritage.

Implémentation

Nous allons créer une interface Shape et une classe d'entité qui implémente l'interface Shape. Ensuite, nous créons une classe de décoration abstraite ShapeDecorator qui implémente l'interface Shape et utilisons l'objet Shape comme variable d'instance.

RedShapeDecorator est une classe d'entité qui implémente ShapeDecorator.

DecoratorPatternDemo, notre classe de démonstration utilise RedShapeDecorator pour décorer l'objet Shape.

decorator_pattern_uml_diagram.jpg

Étape 1

Créer une interface.

Shape.java

public interface Shape {
   void draw();
}

Étape 2

Créez une classe d'entité qui implémente l'interface.

Rectangle.java

public class Rectangle implements Shape {

   @Override
   public void draw() {
      System.out.println("Shape: Rectangle");
   }
}

Circle.java

public class Circle implements Shape {

   @Override
   public void draw() {
      System.out.println("Shape: Circle");
   }
}

Étape 3

Créez une classe de décoration abstraite qui implémente l'interface Shape.

ShapeDecorator.java

public abstract class ShapeDecorator implements Shape {
   protected Shape decoratedShape;

   public ShapeDecorator(Shape decoratedShape){
      this.decoratedShape = decoratedShape;
   }

   public void draw(){
      decoratedShape.draw();
   }	
}

Étape 4

Créez une classe de décoration d'entité qui étend la classe ShapeDecorator.

RedShapeDecorator.java

public class RedShapeDecorator extends ShapeDecorator {

   public RedShapeDecorator(Shape decoratedShape) {
      super(decoratedShape);		
   }

   @Override
   public void draw() {
      decoratedShape.draw();	       
      setRedBorder(decoratedShape);
   }

   private void setRedBorder(Shape decoratedShape){
      System.out.println("Border Color: Red");
   }
}

Étape 5

Utilisez RedShapeDecorator pour décorer l'objet Shape.

DecoratorPatternDemo.java

public class DecoratorPatternDemo {
   public static void main(String[] args) {

      Shape circle = new Circle();

      Shape redCircle = new RedShapeDecorator(new Circle());

      Shape redRectangle = new RedShapeDecorator(new Rectangle());
      System.out.println("Circle with normal border");
      circle.draw();

      System.out.println("\nCircle of red border");
      redCircle.draw();

      System.out.println("\nRectangle of red border");
      redRectangle.draw();
   }
}

Étape 6

Vérifiez la sortie.

Circle with normal border
Shape: Circle

Circle of red border
Shape: Circle
Border Color: Red

Rectangle of red border
Shape: Rectangle
Border Color: Red