Decorator
Problème
Nous souhaitons pouvoir modifier dynamiquement le comportement d'une classe existante.
Cas d'école
Nous avons des personnages dans un jeu modélisé comme suit avec un poids utilisé par le moteur physique :
- Une interface Personnage :
interface Personnage {
getWeight(): number;
}
- Une classe concrète Humain :
class Humain implements Personnage {
getWeight(): number {
return 80.0;
}
}
Nous souhaitons pouvoir modifier les caractéristiques de ces personnages avec l'ajout d'une hache, d'un chapeau,...
Solution
Nous pouvons implémenter hériter de l'interface et nous appuyer sur l'instance originale pour l'implémentation :
class PersonnageAvecHache implements Personnage {
private original: Personnage;
constructor(original: Personnage) {
this.original = original;
}
getWeight(): number {
return this.original.getWeight() + 15.0;
}
}
class PersonnageAvecChapeau implements Personnage {
private original: Personnage;
constructor(original: Personnage) {
this.original = original;
}
public getWeight(): number {
return this.original.getWeight() + 2.0;
}
}
A l'usage :
let personnage = new Humain();
personnage = new PersonnageAvecHache(personnage);
personnage = new PersonnageAvecChapeau(personnage);
console.log(personnage.getWeight()) // 80 + 15 + 2
Autres cas d'école
RetryingHttpClient
décorantHttpClient
avec plusieurs tentatives sur les requêtes GET .HideSecretLogger
décorantLogger
pour masquer des secrets dans les messages des journaux applicatifs.- FilteredReportBuilder décorant ReportBuilder pour limiter le nombre d'erreur d'un même type dans un rapport de validation de données
- ...