Middle
Cum funcționează un decorator în PHP?
sobes.tech AI
Răspuns de la AI
Modelul "Decorator" adaugă dinamic un comportament nou unui obiect existent învelindu-l într-un alt obiect numit decorator.
-
Componente:
- Interfață (Component): Declară metode comune pentru obiectul original și decoratorii săi.
- Component concret (Concrete Component): Obiectul principal care trebuie decorat.
- Decorator de bază (Decorator): Clasă abstractă sau interfață care conține o referință la un obiect al interfeței (Component) și implementează metodele sale, de obicei delegând apelul către acel obiect.
- Decoratori concreți (Concrete Decorators): Implementează noi funcționalități, completând sau modificând comportamentul componentului de bază.
-
Principiul de funcționare:
- Decoratorul conține o referință la obiectul pe care îl decorează (compoziție).
- Are aceeași interfață ca obiectul decorat.
- La apelarea unei metode pe decorator, acesta efectuează logică suplimentară înainte sau după apelul metodei corespunzătoare pe obiectul decorat, sau îl înlocuiește complet (deși acesta din urmă nu este o utilizare tipică).
-
Avantaje:
- Permite adăugarea de funcționalități obiectelor în timpul execuției, nu static prin moștenire.
- Evită "explozia" ierarhiei de clase la combinarea mai multor comportamente diferite.
- Permite crearea de combinații flexibile de comportamente.
-
Exemplu:
<?php
// Interfața componentului
interface Coffee {
public function getCost(): float;
public function getDescription(): string;
}
// Component concret
class SimpleCoffee implements Coffee {
public function getCost(): float {
return 5.0;
}
public function getDescription(): string {
return "Cafea simplă";
}
}
// Decorator de bază
abstract class CoffeeDecorator implements Coffee {
protected Coffee $coffee;
public function __construct(Coffee $coffee) {
$this->coffee = $coffee;
}
public function getCost(): float {
return $this->coffee->getCost();
}
public function getDescription(): string {
return $this->coffee->getDescription();
}
}
// Decorator concret: Adăugare lapte
class MilkDecorator extends CoffeeDecorator {
public function getCost(): float {
return parent::getCost() + 2.0;
}
public function getDescription(): string {
return parent::getDescription() . ", cu lapte";
}
}
// Decorator concret: Adăugare zahăr
class SugarDecorator extends CoffeeDecorator {
public function getCost(): float {
return parent::getCost() + 1.0;
}
public function getDescription(): string {
return parent::getDescription() . ", cu zahăr";
}
}
// Utilizare:
// Creăm o cafea simplă
$coffee = new SimpleCoffee();
echo $coffee->getDescription() . " - " . $coffee->getCost() . "\n"; // Cafea simplă - 5
// Adăugăm lapte
$coffeeWithMilk = new MilkDecorator($coffee);
echo $coffeeWithMilk->getDescription() . " - " . $coffeeWithMilk->getCost() . "\n"; // Cafea simplă, cu lapte - 7
// Adăugăm zahăr
$coffeeWithMilkAndSugar = new SugarDecorator($coffeeWithMilk);
echo $coffeeWithMilkAndSugar->getDescription() . " - " . $coffeeWithMilkAndSugar->getCost() . "\n"; // Cafea simplă, cu lapte, cu zahăr - 8