Sobes.tech
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