Middle
Hoe werkt een decorator in PHP?
sobes.tech AI
Antwoord van AI
Het "Decorator"-patroon voegt dynamisch nieuw gedrag toe aan een bestaand object door het te omhullen in een ander object, de decorator genoemd.
-
Componenten:
- Interface (Component): Declareert gemeenschappelijke methoden voor het oorspronkelijke object en zijn decorateurs.
- Concreet Component (Concrete Component): Het hoofdobject dat gedecoreerd moet worden.
- Basis Decorator (Decorator): Abstracte klasse of interface die een verwijzing bevat naar een object van de interface (Component) en zijn methoden implementeert, meestal door de aanroep door te sturen naar dat object.
- Concreet Decorateurs (Concrete Decorators): Implementeren nieuwe functionaliteiten, aanvullend op of wijzigend het gedrag van de basiscomponent.
-
Werking:
- De decorator bevat een verwijzing naar het object dat hij decoreert (compositie).
- Heeft dezelfde interface als het te decoreren object.
- Bij het aanroepen van een methode op de decorator, voert hij of extra logica uit voor of na het aanroepen van de overeenkomstige methode op het gedecoreerde object, of vervangt hij deze volledig (hoewel dit laatste niet typisch is).
-
Voordelen:
- Maakt het mogelijk om functionaliteit toe te voegen aan objecten tijdens de uitvoering, niet statisch via overerving.
- Vermijdt de "explosie" van de klassehiërarchie bij het combineren van meerdere verschillende gedragingen.
- Maakt het mogelijk om flexibele combinaties van gedragingen te creëren.
-
Voorbeeld:
<?php
// Component interface
interface Coffee {
public function getCost(): float;
public function getDescription(): string;
}
// Concreet component
class SimpleCoffee implements Coffee {
public function getCost(): float {
return 5.0;
}
public function getDescription(): string {
return "Eenvoudige koffie";
}
}
// Basis Decorator
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();
}
}
// Concreet Decorator: Mel toevoegen
class MilkDecorator extends CoffeeDecorator {
public function getCost(): float {
return parent::getCost() + 2.0;
}
public function getDescription(): string {
return parent::getDescription() . ", met melk";
}
}
// Concreet Decorator: Suiker toevoegen
class SugarDecorator extends CoffeeDecorator {
public function getCost(): float {
return parent::getCost() + 1.0;
}
public function getDescription(): string {
return parent::getDescription() . ", met suiker";
}
}
// Gebruik:
// Maak een eenvoudige koffie
$coffee = new SimpleCoffee();
echo $coffee->getDescription() . " - " . $coffee->getCost() . "\n"; // Eenvoudige koffie - 5
// Voeg melk toe
$coffeeWithMilk = new MilkDecorator($coffee);
echo $coffeeWithMilk->getDescription() . " - " . $coffeeWithMilk->getCost() . "\n"; // Eenvoudige koffie, met melk - 7
// Voeg suiker toe
$coffeeWithMilkAndSugar = new SugarDecorator($coffeeWithMilk);
echo $coffeeWithMilkAndSugar->getDescription() . " - " . $coffeeWithMilkAndSugar->getCost() . "\n"; // Eenvoudige koffie, met melk, met suiker - 8