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.

Tagi : , ,

Napisz komentarz