Le Design Pattern Décorateur pour l'Extension Dynamique

Le design pattern Décorateur, un pattern structurel, permet d'ajouter des responsabilités supplémentaires à un objet de manière dynamique et transparente. Il s'agit d'une alternative flexible à l'héritage, où le comportement est étendu sans altérer la structure originale de l'objet. Ce pattern est couramment utilisé dans les scénarios nécessitant une modification des fonctionnalités à l'exécution.

Principe fondamental : Encapsuler un objet existant dans une classe décoratrice qui fournit des méthodes supplémentaires, tout en conservant l'interface de l'objet original. Ainsi, les extensions peuvent être combinées de façon modulaire.

Cas d'application : Lorsque l'on doit enrichir les capacités d'une classe sans recourir à la modification directe de son code ou à la création de multiples sous-classes.

Pour illustrer ce pattern, considérons un exemple où nous modélisons un système de composition de plats. Définissons d'abord une classe abstraite représentant un plat de base.


public abstract class Plat {
    public abstract String preparer();
}

Implémentons une classe concrète pour un plat simple, comme une salade de base.


public class SaladeBase extends Plat {
    @Override
    public String preparer() {
        return "Salade verte avec vinaigrette";
    }
}

Ensuite, créons un décoratuer abstrait qui étend la classe Plat et maintient une référence à un objet Plat.


public abstract class DecorateurPlat extends Plat {
    protected Plat plat;

    public DecorateurPlat(Plat plat) {
        this.plat = plat;
    }

    @Override
    public String preparer() {
        return plat.preparer();
    }
}

Ajoutons des décorateurs concrets pour des ingrédients supplémentaires, comme des protéines ou des garnitures.


public class AvecProteines extends DecorateurPlat {
    public AvecProteines(Plat plat) {
        super(plat);
    }

    private String ajouterPoulet() {
        return ", poulet grillé";
    }

    @Override
    public String preparer() {
        return plat.preparer() + ajouterPoulet();
    }
}

public class AvecGarniture extends DecorateurPlat {
    public AvecGarniture(Plat plat) {
        super(plat);
    }

    private String ajouterFromage() {
        return ", parmesan";
    }

    @Override
    public String preparer() {
        return plat.preparer() + ajouterFromage();
    }
}

Dans une classe de test, nous pouvons chaîner les décorateurs pour construire dynamiquement un plat complexe.


public class TestSystemePlat {
    public static void main(String[] args) {
        Plat platSimple = new SaladeBase();
        System.out.println(platSimple.preparer());

        Plat platAvecProteines = new AvecProteines(platSimple);
        System.out.println(platAvecProteines.preparer());

        Plat platComplet = new AvecGarniture(platAvecProteines);
        System.out.println(platComplet.preparer());
    }
}

La sortie produite sera :

Salade verte avec vinaigrette
Salade verte avec vinaigrette, poulet grillé
Salade verte avec vinaigrette, poulet grillé, parmesan

Cette structure permet d'ajouter ou de retirer des fonctionnalités de manière non intrusive, en appliquant plusieurs couches de décorateurs à l'objet central.

Étiquettes: Decorator Pattern Java Structural Patterns Object-Oriented Design

Publié le 17 juillet à 17h41