Sobes.tech
Middle

Чӣ гуна кор мекунад декоратор дар PHP?

sobes.tech AI

Ҷавоб аз AI

Нигмата "Декоратор" динамично илова ново поведение на постоечки објект, обвивајќи го во друг објект наречен декоратор.

  • Компоненти:

    • Интерфејс (Component): Ја објавува заедничката метода за оригиналниот објект и неговите декоратори.
    • Конкретен компонент (Concrete Component): Основниот објект што треба да се декорира.
    • Базен декоратор (Decorator): Абрстрактна класа или интерфејс што содржи референца на објект од интерфејсот (Component) и ја реализира неговата метода, обично делегирајќи ја повикот на тој објект.
    • Конкретни декоратори (Concrete Decorators): Реализираат нови можности, дополнувајќи или менувајќи го однесувањето на основниот компонент.
  • Принцип на работа:

    • Декоратор содржи референца на објектот што го декорира (композиција).
    • Декоратор има истиот интерфејс, како и декорираниот објект.
    • При повик на метод од декораторот, тој или извршува дополнителна логика пре или по повикот на соодветната метода од декорираниот објект, или го заменува целосно (иако ова последното не е типична употреба).
  • Предности:

    • Овозможува додавање на функционалност на објектите во текот на извршувањето, а не со статичко наследување.
    • Избегнува "распаѓање" на хиерархијата на класи при комбинирање на различни однесувања.
    • Овозможува создавање на флексибилни комбинации од однесувања.
  • Пример:

<?php

// Интерфејс на компонента
interface Coffee {
    public function getCost(): float;
    public function getDescription(): string;
}

// Конкретен компонент
class SimpleCoffee implements Coffee {
    public function getCost(): float {
        return 5.0;
    }

    public function getDescription(): string {
        return "Обична кафе";
    }
}

// Аборстрактен декоратор
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();
    }
}

// Конкретен декоратор: додавање млеко
class MilkDecorator extends CoffeeDecorator {
    public function getCost(): float {
        return parent::getCost() + 2.0;
    }

    public function getDescription(): string {
        return parent::getDescription() . ", со млеко";
    }
}

// Конкретен декоратор: додавање шеќер
class SugarDecorator extends CoffeeDecorator {
    public function getCost(): float {
        return parent::getCost() + 1.0;
    }

    public function getDescription(): string {
        return parent::getDescription() . ", со шеќер";
    }
}

// Користење:
// Создавање обична кафе
$coffee = new SimpleCoffee();
echo $coffee->getDescription() . " - " . $coffee->getCost() . "\n"; // Обична кафе - 5

// Додавање млеко
$coffeeWithMilk = new MilkDecorator($coffee);
echo $coffeeWithMilk->getDescription() . " - " . $coffeeWithMilk->getCost() . "\n"; // Обична кафе, со млеко - 7

// Додавање шеќер
$coffeeWithMilkAndSugar = new SugarDecorator($coffeeWithMilk);
echo $coffeeWithMilkAndSugar->getDescription() . " - " . $coffeeWithMilkAndSugar->getCost() . "\n"; // Обична кафе, со млеко, со шеќер - 8