Ce este
Șablonul Decorator adaugă comportament unui obiect învelindu-l într-un alt obiect cu aceeași interfață. Fiecare înveliș își face partea suplimentară și transmite apelul mai departe către ceea ce învelește.
Fiindcă învelișul și obiectul învelit împart interfața, învelișurile se stivuiesc în orice combinație — ca straturile de haine.
Exemplu: învelirea unui notificator
Notificatorul simplu trimite un e-mail. Un înveliș adaugă jurnalizarea înainte de trimitere; altul adaugă un SMS după ea. Apelantul vede în continuare un simplu Notifier.
Straturi în jurul unui nucleu
new WithLog(new WithSMS(new EmailNotifier())) se citește dinspre interior spre exterior: e-mailul în nucleu, SMS-ul în jurul lui, jurnalizarea cel mai în afară. Orice strat poate fi adăugat, eliminat sau reordonat fără a atinge celelalte.
Ieșire: script PHP
<?php
interface Notifier {
public function send(string $msg): void;
}
class EmailNotifier implements Notifier {
public function send(string $msg): void {
echo "email: ", $msg, "\n";
}
}
// Fiecare decorator învelește un Notifier și adaugă un singur strat.
class WithLog implements Notifier {
public function __construct(private Notifier $wrapped) {}
public function send(string $msg): void {
echo "log: se trimite o notificare\n";
$this->wrapped->send($msg);
}
}
class WithSMS implements Notifier {
public function __construct(private Notifier $wrapped) {}
public function send(string $msg): void {
$this->wrapped->send($msg);
echo "sms: ", $msg, "\n";
}
}
$n = new WithLog(new WithSMS(new EmailNotifier()));
$n->send("server is down");
Când să îl folosești
Folosește-l pentru a adăuga comportament opțional și combinabil — jurnalizare, memorare în cache, reîncercări, metrici — în jurul unui nucleu pe care nu vrei să îl modifici. Middleware-ul HTTP din aplicațiile PHP învelește exact în acest fel gestionarele de cereri.
Renunță la el când comportamentul nu este opțional și nu este combinabil — atunci el aparține clasei înseși, unde este mai ușor de găsit.
Avantaje și dezavantaje
Avantaje: comportamentul este adăugat fără a atinge clasa-nucleu; straturile se combină liber; fiecare strat este mic și poate fi testat singur.
Dezavantaje: o stivă adâncă de învelișuri este greu de depanat — apelul parcurge un drum lung înainte de a face ceva; liniile de construcție devin lungi.