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 l'interface en nous appuyant sur une instance existante comme suit :
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¶
RetryingHttpClientdécorantHttpClientavec plusieurs tentatives sur les requêtes GET .HideSecretLoggerdécorantLoggerpour 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
- ...