Wzorzec Stan umożliwia zmianę zachowania obiektu, kiedy zmianie ulegnie jego wewnętrzny stan. Wzorzec ten jest bardzo użyteczny i występuje praktycznie wszędzie. Przykładem z życia może być np: przełącznik światła, który posiada dwa stany: włączony (ON) i wyłączony (OFF).
Dla przykładu zbudujemy taki minimalistyczny przełącznik 🙂
Pierwsza klasa stanu – State, jest abstrakcyjna i posiada również abstrakcyjną metodę change, która będzie zmieniać aktualny stan na inny (ale to dopiero w implementacji 😉 ). Metoda ta, poprzez typowanie przyjmuje instancję klasy Context.
1 2 3 4 5 6 7 8 9 10 |
<?php // State.php abstract class State { abstract public function change(Context $context); } ?> |
Klasa Context – jest najważniejsza i pozwala na bieżąco śledzić stan obiektu:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<?php // Context.php class Context { private $state; public function __construct(State $object) { $this->state = $object; } public function setState($state) { $this->state = $state; } public function getState() { return $this->state; } public function Run() { $this->state->change($this); } } ?> |
Konstruktor pobiera obiekt stanu: State $object. Metoda setState ustawia aktualny stan obiektu, a getState zwraca go. Metoda Run – to tzw. “wyzwalacz” i zmienia stan (za pomocą metody change) z aktualnego na inny. W poniższych klasach “stanu” (On / Off) będzie to widoczne.
Klasa On:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?php // On.php class On extends State { public function change(Context $context) { echo '<p> ON </p>'; $context->setState(new Off()); } } ?> |
Klasa Off:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?php // Off.php class Off extends State { public function change(Context $context) { echo '<p> OFF </p>'; $context->setState(new On()); } } ?> |
Obie klasy zmieniają kontekst, ustawiając (w pamięci) przeciwne stany po wykonaniu operacji ON lub OFF:
1 2 3 4 5 6 7 |
echo '<p> ON </p>'; // włączone ON $context->setState(new Off()); // ustawia OFF // analogicznie dla OFF: echo '<p> OFF </p>'; $context->setState(new On()); |
Potrzebujemy jeszcze klasy klienta (Client), której użyjemy do zabawy przełącznikiem:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<?php // Client.php spl_autoload_register(function ($class_name) { include $class_name . '.php'; }); $state = new Off(); // domyślnie: OFF $context = new Context($state); // aktualny stan: OFF // "zabawa" przełącznikiem :) : $context->Run(); // OFF $context->Run(); // ON $context->Run(); // OFF $context->Run(); // ON // ... ?> |
WZORCE PROJEKTOWE
Wzorce kreacyjne
Wzorce strukturalne
- Adapter
- Dekorator (Decorator)
- Fasada (Facade)
- Płynny interfejs (Fluent Interface)
- Pełnomocnik (Proxy)
Wzorce czynnościowe
- Metoda szablonowa (Template Method)
- Obserwator (Observer)
- Stan (State)
- Strategia (Strategy)
- Wstrzykiwanie zależności (Dependency Injection)