Middle
Kaip veikia dekoratorius PHP?
sobes.tech AI
Atsakymas iš AI
Dekoratoriaus šablonas dinamiškai prideda naują elgseną esamam objektui, jį apvyniojant kitu objektu, vadinamu dekoratoriumi.
-
Sudedamosios dalys:
- Sąsaja (Component): Deklaruoja bendrus metodus pradiniam objektui ir jo dekoratoriams.
- Konkreti sudedamoji dalis (Concrete Component): Pagrindinis objektas, kurį reikia dekoruoti.
- Pagrindinis dekoratorius (Decorator): Abstrakti klasė arba sąsaja, kuri turi nuorodą į sąsajos objektą (Component) ir įgyvendina jo metodus, dažniausiai deleguodama iškvietimą šiam objektui.
- Konkrečios dekoratoriai (Concrete Decorators): Įgyvendina naujas galimybes, papildydami arba keisdami pagrindinio komponento elgseną.
-
Veikimo principas:
- Dekoratorius turi nuorodą į objektą, kurį dekoruoja (kompozicija).
- Dekoratorius turi tą pačią sąsają, kaip ir dekoruojamas objektas.
- Kai kviečiame metodą dekoratoriuje, jis arba atlieka papildomą logiką prieš arba po atitinkamo metodo iškvietimo dekoruojamame objekte, arba jį visiškai pakeičia (nors tai nėra įprasta naudojimo būdas).
-
Privalumai:
- Leidžia pridėti funkcionalumą objektams vykdymo metu, o ne statinio paveldėjimo būdu.
- Vengia "sprogimo" klasės hierarchijoje, kai derinami įvairūs elgesiai.
- Leidžia kurti lankstesnius elgesio derinius.
-
Pavyzdys:
<?php
// Komponento sąsaja
interface Coffee {
public function getCost(): float;
public function getDescription(): string;
}
// Konkreti sudedamoji dalis
class SimpleCoffee implements Coffee {
public function getCost(): float {
return 5.0;
}
public function getDescription(): string {
return "Paprastas kavos";
}
}
// Abstraktus dekoratorius
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();
}
}
// Konkretaus dekoratoriaus pavyzdys: pridėti pieno
class MilkDecorator extends CoffeeDecorator {
public function getCost(): float {
return parent::getCost() + 2.0;
}
public function getDescription(): string {
return parent::getDescription() . ", su pienu";
}
}
// Konkretaus dekoratoriaus pavyzdys: pridėti cukraus
class SugarDecorator extends CoffeeDecorator {
public function getCost(): float {
return parent::getCost() + 1.0;
}
public function getDescription(): string {
return parent::getDescription() . ", su cukrumi";
}
}
// Naudojimas:
// Sukurkite paprastą kavą
$coffee = new SimpleCoffee();
echo $coffee->getDescription() . " - " . $coffee->getCost() . "\n"; // Paprasta kava - 5
// Pridėti pieno
$coffeeWithMilk = new MilkDecorator($coffee);
echo $coffeeWithMilk->getDescription() . " - " . $coffeeWithMilk->getCost() . "\n"; // Paprasta kava, su pienu - 7
// Pridėti cukraus
$coffeeWithMilkAndSugar = new SugarDecorator($coffeeWithMilk);
echo $coffeeWithMilkAndSugar->getDescription() . " - " . $coffeeWithMilkAndSugar->getCost() . "\n"; // Paprasta kava, su pienu, su cukrumi - 8