Middle
Hogyan működik egy dekorátor PHP-ben?
sobes.tech MI
Válasz az MI-től
A "Díszítő" minta dinamikusan ad hozzá új viselkedést egy meglévő objektumhoz, egy másik objektumba csomagolva, amit díszítőnek nevezünk.
-
Összetevők:
- Interfész (Component): Általános módszereket deklarál az eredeti objektumhoz és díszítőihez.
- Konkrét Komponens (Concrete Component): Az alapvető objektum, amelyet díszíteni kell.
- Alap Díszítő (Decorator): Egy absztrakt osztály vagy interfész, amely tartalmaz egy hivatkozást egy interfész objektumra (Component) és megvalósítja annak módszereit, általában delegálva a hívást erre az objektumra.
- Konkrét Díszítők (Concrete Decorators): Új lehetőségeket valósítanak meg, kiegészítve vagy módosítva az alapkomponens viselkedését.
-
Működési elv:
- A díszítő tartalmaz egy hivatkozást arra az objektumra, amit díszít (összetétel).
- A díszítő ugyanazzal az interfésszel rendelkezik, mint a díszített objektum.
- Amikor a díszítőn meghívunk egy metódust, az vagy további logikát hajt végre az vagy után a hívás előtt, vagy teljesen helyettesíti azt (bár ez nem tipikus használat).
-
Előnyök:
- Lehetővé teszi a funkcionalitás hozzáadását objektumokhoz futásidőben, nem statikus örökléssel.
- Elkerüli a osztályhierarchia "robbanását" különböző viselkedések kombinálásakor.
- Lehetővé teszi rugalmas viselkedéskombinációk létrehozását.
-
Példa:
<?php
// Komponens interfész
interface Coffee {
public function getCost(): float;
public function getDescription(): string;
}
// Konkrét komponens
class SimpleCoffee implements Coffee {
public function getCost(): float {
return 5.0;
}
public function getDescription(): string {
return "Egyszerű kávé";
}
}
// Alap díszítő
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();
}
}
// Konkrét díszítő: tej hozzáadása
class MilkDecorator extends CoffeeDecorator {
public function getCost(): float {
return parent::getCost() + 2.0;
}
public function getDescription(): string {
return parent::getDescription() . ", tejjel";
}
}
// Konkrét díszítő: cukor hozzáadása
class SugarDecorator extends CoffeeDecorator {
public function getCost(): float {
return parent::getCost() + 1.0;
}
public function getDescription(): string {
return parent::getDescription() . ", cukorral";
}
}
// Használat:
// Egyszerű kávé létrehozása
$coffee = new SimpleCoffee();
echo $coffee->getDescription() . " - " . $coffee->getCost() . "\n"; // Egyszerű kávé - 5
// Tej hozzáadása
$coffeeWithMilk = new MilkDecorator($coffee);
echo $coffeeWithMilk->getDescription() . " - " . $coffeeWithMilk->getCost() . "\n"; // Egyszerű kávé, tejjel - 7
// Cukor hozzáadása
$coffeeWithMilkAndSugar = new SugarDecorator($coffeeWithMilk);
echo $coffeeWithMilkAndSugar->getDescription() . " - " . $coffeeWithMilkAndSugar->getCost() . "\n"; // Egyszerű kávé, tejjel, cukorral - 8