Menu
Coddy logo textTech

Patron Décorateur

Fait partie de la section Programmation Orientée Objet du Journey Java de Coddy. Leçon 72 sur 87.

Le patron Décorateur est un patron de conception structurel qui vous permet d’ajouter de nouveaux comportements aux objets en les enveloppant dans des objets spéciaux appelés décorateurs. Contrairement à l’héritage, qui ajoute un comportement lors de la compilation, les décorateurs ajoutent dynamiquement des fonctionnalités à l’exécution sans modifier la classe d’origine.

Imaginez un café où vous commencez avec un café de base et pouvez ajouter des suppléments comme du lait, du sucre ou de la crème fouettée. Chaque ajout enveloppe le café original en lui ajoutant son coût et sa description. Le patron utilise une interface commune afin que les objets décorés puissent être traités de la même manière que l’original :

interface Coffee {
    String getDescription();
    double getCost();
}

class SimpleCoffee implements Coffee {
    public String getDescription() {
        return "Simple Coffee";
    }
    public double getCost() {
        return 2.0;
    }
}

abstract class CoffeeDecorator implements Coffee {
    protected Coffee coffee;
    
    public CoffeeDecorator(Coffee coffee) {
        this.coffee = coffee;
    }
}

class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee coffee) {
        super(coffee);
    }
    
    public String getDescription() {
        return coffee.getDescription() + ", Milk";
    }
    
    public double getCost() {
        return coffee.getCost() + 0.5;
    }
}

Le décorateur conserve une référence vers l’objet enveloppé et lui délègue les appels tout en ajoutant son propre comportement. Vous pouvez empiler plusieurs décorateurs pour combiner des fonctionnalités :

Coffee order = new SimpleCoffee();
order = new MilkDecorator(order);
order = new SugarDecorator(order);

System.out.println(order.getDescription());  // Simple Coffee, Milk, Sugar
System.out.println(order.getCost());         // 2.75

Le patron Decorator est particulièrement utile lorsque vous devez ajouter des responsabilités à des objets sans créer une multitude de sous-classes. Chaque décorateur est indépendant, ce qui vous permet de les combiner librement afin de créer exactement la combinaison de comportements dont vous avez besoin.

challenge icon

Défi

Facile

Construisons un système de notifications avec le Decorator Pattern ! Vous allez créer une notification de base qui peut être enrichie avec différents canaux de diffusion — alertes par e-mail, alertes SMS et notifications push — en imbriquant des décorateurs les uns autour des autres. Cela reflète les systèmes du monde réel dans lesquels un même message peut devoir être envoyé simultanément par plusieurs canaux.

Vous allez organiser votre code dans quatre fichiers :

  • Notifier.java : Define l’interface Notifier qui sert d’interface de composant pour votre Decorator Pattern. Elle doit déclarer une méthode send(String message) qui gère l’envoi des notifications.
  • BasicNotifier.java : Create la classe de composant concrete qui implements Notifier. Elle représente la forme la plus simple d’une notification : une alerte dans l’application. Lorsque send est appelé, elle doit afficher In-App: [message].
  • NotifierDecorators.java : Construisez votre hiérarchie de décorateurs ici. Commencez par une classe abstract NotifierDecorator qui implements Notifier et contient une référence vers un objet Notifier enveloppé (transmise par son constructor).

    Créez ensuite trois décorateurs concrets qui étendent NotifierDecorator :

    EmailDecorator — Lorsque send est appelé, il délègue d’abord au notificateur enveloppé, puis affiche Email: [message].

    SMSDecorator — Lorsque send est appelé, il délègue d’abord au notificateur enveloppé, puis affiche SMS: [message].

    PushDecorator — Lorsque send est appelé, il délègue d’abord au notificateur enveloppé, puis affiche Push: [message].

  • Main.java : Assemblez votre système de décorateurs ! Vous recevrez deux entrées : le message de notification (String) et une liste de canaux à ajouter, séparés par des virgules (String), par exemple "email,sms" ou "push,email,sms".

    Commencez avec un BasicNotifier. Ensuite, selon l’entrée contenant les canaux, enveloppez-le avec les décorateurs appropriés dans l’ordre où ils apparaissent. Les noms de canaux valides sont email, sms et push.

    Enfin, appelez send avec votre message sur le notificateur entièrement décoré.

Vous recevrez deux entrées dans l’ordre suivant : le message à envoyer (String), puis les canaux à activer (String, séparés par des virgules).

Par exemple, avec les entrées Server is down! et email,push, votre sortie serait :

In-App: Server is down!
Email: Server is down!
Push: Server is down!

Remarquez comment chaque décorateur ajoute son propre comportement tout en préservant la notification d’origine. L’ordre d’imbrication détermine l’ordre de la sortie : le composant le plus interne (BasicNotifier) s’exécute en premier, puis chaque décorateur ajoute sa couche. Vous pouvez combiner librement n’importe quels canaux sans créer de classes distinctes pour chaque combinaison !

Essayez vous-même

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Lire le message à envoyer
        String message = scanner.nextLine();
        
        // Lire la liste des canaux séparés par des virgules (p. ex., "email,sms" ou "push,email,sms")
        String channelsInput = scanner.nextLine();
        
        // TODO: Commencer avec un BasicNotifier
        
        // TODO: Diviser l'entrée des canaux par une virgule
        
        // TODO: Parcourir chaque canal et envelopper le notificateur avec le décorateur approprié
        // Les canaux valides sont : "email", "sms", "push"
        
        // TODO: Appeler send sur le notificateur entièrement décoré avec le message
        
    }
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation Orientée Objet

Entraînez-vous par vous-même : Compilateur Java en ligne