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