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