9
Wzorzec decorator należy do wzorców strukturalnych. W praktyce umożliwia dynamiczne dodawanie nowych funkcji do istniejących klas bez ich fizycznej modyfikacji. Dzięki temu można rozszerzyć możliwości klasy bez ingerowania w jej kod pozostawiając jej oryginalną funkcjonalność.
Aby pokazać działanie wzorca decorator posłużę się prostym przykładem. Załóżmy, że mam klasę zapisującą dane do bazy. Nie chcę zmieniać jej kodu i funkcjonalności ale chcę ją rozszerzyć o walidację danych. Mógłbym zastosować dziedziczenie i wykorzystać dziedziczoną metodą do walidacji ale wówczas musiałbym zmodyfikować kod klasy głównej czego bardzo chcę uniknąć a dodatkowo każda zmiana klasy dziedziczącej wymuszałaby zmiany klas dziedziczonych.
Zacznę od stworzenia wspólnego interfejsu dla klasy dekorowanej i dekoratora:
-
interface IDecorator
-
{
-
function save();
-
}
Następnie stworzę klasę główną (dekorowaną) implementującą interfejs IDecorator, której kodu podczas rozszerzania nie mam zamiaru modyfikować:
-
class Decorable imlements IDecorator
-
{
-
function save()
-
{
-
// zapis danych do bazy
-
// [...]
-
}
-
}
Teraz przyszła kolej na stworzenie klasy dekorującej czyli wzbogacającej klasę główną Decorable o funkcję walidującą dane, która także implementuje interfejs IDecorator:
-
class Decorate implements IDecorator
-
{
-
/**
-
* Obiekt klasy dekorowanej
-
*
-
* @var object
-
* @access private
-
*/
-
private $_decorate;
-
-
/**
-
* Konstruktor klasy
-
*
-
* @param object $decorable
-
*/
-
function __construct(Decorable $decorable)
-
{
-
// przypisanie obiektu klasy dekorowanej do zmiennej prywatnej
-
$this->_decorable = $decorable
-
}
-
-
/**
-
* Metoda uruchamia walidacje danych
-
*/
-
function save()
-
{
-
// walidacja danych
-
// [...]
-
-
// wywolanie oryginalnej metody z klasy dekorowanej
-
$this->_decorable->save();
-
}
-
}
Do konstruktora klasy zostaje przekazany obiekt oryginalnej klasy dekorowanej Decorable. Na koniec pozostaje mi stworzenie obiektu klasy dekorowanej Decorable i przekazanie jej klasie dekorującej Decorate:
-
$action = new Decorate(new Decorable());
-
$action->save();
Po stworzeniu obiektu klasy Decorable wywołuję metodę save(), która po przeprowadzeniu walidacji wywołuje metodę o tej samej nazwie klasy dekorowanej Decorable.
Jak więc widać rozszerzyłem funkcjonalność klasy oryginalnej nie dokonując w niej żadnych istotnych zmian. Podsumowując dekoratory są w pewnym sensie alternatywą dla dziedziczenia. Dziedziczenie rozszerza zachowanie klasy w trakcie kompilacji, w przeciwieństwie do dekoratorów, które rozszerzają klasy w czasie działania programu.
Więcej o wzorcu dekoratora:
http://pl.wikipedia.org/wiki/Wzorzec_dekoratora
http://4programmers.net/PHP/Wzorce_Projektowe#id-Dekorator
http://www.phppatterns.com/docs/design/decorator_pattern
http://www.fluffycat.com/PHP-Design-Patterns/Decorator
http://www.vincehuston.org/dp/decorator.html
Leave a Reply
You must be logged in to post a comment.