Napisany sie-16-2009
dekorator
Dekorator to wzorzec projektowy, który z wykorzystaniem kompozycji obiektów, pozwala na dynamiczne dołączanie do klas nowych funkcjonalności. Składa się z obiektu dekorowanego i dekoratorów. Obiekt dekorowany to instancja klasy, którą zamierzamy wzbogacić o dodatkowe zadania. Dekoratory implementują nowe zachowania, aby na końcu delegować wykonanie konkretnych operacji do obiektu dekorowanego. Choć po takim wprowadzeniu ów wzorzec może się wydawać skomplikowany, to w rzeczywistości jest prosty i niezwykle przydatny. Aby zrozumieć sposób jego działania proponuje zapoznać się z poniższym przykładem.
Prosty przykład
Wyobraźmy sobie abstrakcyjną klasę Information, której jedynym zadaniem jest wypisywanie na wyjście wiadomości przekazanej w parametrze metody Write($message). Spójrzmy na poniższy listing.
abstract class Information {
abstract public function Write($message);
}
Zatem najprostsza implementacja powyższej klasy może wyglądać następująco:
// obiekty tej klasy beda dekorowane
class SimpleText extends Information {
public function Write ($message) {
echo $message;
}
}
Nie chcemy jednak, by każdy łańcuch znaków mógł zostać wyświetlony. W związku z tym stworzymy teraz klasy, które zapewnią walidację parametru $message.
// klasa sprawdza dlugosc string'a.
class TextLength extends Information {
// obiekt dekorowany
private $decorate;
public function __construct (Information $dec) {
// korzystamy z kompozycji obiektow
$this->decorate = $dec;
}
public function Write ($message) {
// warunek wyswietlenia string'a
if (isset($message{5}))
$this->decorate->Write($message);
}
}
// klasa sprawdza czy pierwsza litera wiadomosci jest A
class FirstLetter extends Information {
// obiekt dekorowany
private $decorate;
public function __construct (Information $dec) {
//korzystamy z kompozycji obiektow
$this->decorate = $dec;
}
public function Write ($message) {
//warunek walidacji
if ($message{0}=='A')
$this->decorate->Write($message);
}
}
Jeśli chcemy zezwolić na wyświetlanie na wyjściu wiadomości, których długość przekracza pięć znaków wystarczy zapis:
$obj = new TextLength(new SimpleText());
$obj->Write('Napis');
Warunki mogą być łatwo dołączane jak zaprezentowano poniżej:
// wyswietli napis gdy bedzie on mial wiecej niz
// 5 znakow a pierwszym bedzie litera A.
$obj = new FirstLetter(new TextLength(new SimpleText()));
$obj->Write('Napis');
W ten prosty sposób możemy dowolnie nakładać ograniczenia na parametr $message. Proszę zwrócić uwagę na fakt, iż gdy obiekt dekorowany jest tego samego typu co dekoratory jesteśmy w stanie “dekorować” również dekoratory - tak właśnie dzieje się w powyższym przykładzie. Zachęcam do korzystania z tego wzorca.
