Autor wpisu: Łukasz Socha, dodany: 09.09.2012 21:04, tagi: php
pobierz w .pdf(przeznaczone do wydruku)
Głównym obszarem wykorzystania wzorca Obserwator jest stworzenie relacji typu jeden-do-wielu łączącej grupę obiektów. Dzięki zastosowaniu wzorca zmiana stanu (czyli zmiana aktualnych wartości pól) obiektu obserwowanego umożliwi automatyczne powiadomienie o niej wszystkich innych dołączanych elementów (obserwatorów).
Diagram klas wzorca Observer
Interfejs Subject definiuje operacje attach() i detach() pozwalające odpowiednio na dołączanie i odłączanie obserwatorów. Ponadto zdefiniowana jest też operacja notify(), służąca do powiadamiania wszystkich zarejestrowanych obserwatorów o zmianie stanu obiekt obserwowanego poprzez wywołanie w pętli metody update(), która jest zadeklarowana w interfejsie Observer. Operacja ta jest implementowana w klasie realizującej ten interfejs i służy do powiadamiania konkretnego obserwatora o zmianie stanu obiektu obserwowanego.
Przykładowa implementacja
<?php
class Observer1 implements SplObserver {
public function update(SplSubject $subject) {
echo 'Aktualizacja Observer1';
}
}
class Observer2 implements SplObserver {
public function update(SplSubject $subject) {
echo 'Aktualizacja Observer2';
}
}
class Subject implements SplSubject {
protected $observers = array();
public function attach(SplObserver $observer) {
$this->observers[spl_object_hash($observer)] = $observer;
}
public function detach(SplObserver $observer) {
unset($this->observers[spl_object_hash($observer)]);
}
public function notify() {
foreach ($this->observers as $observer) {
$observer->update($this);
}
}
}
$subject = new Subject();
$observer1 = new Observer1();
$observer2 = new Observer2();
$subject->attach($observer1);
$subject->attach($observer2);
$subject->notify();
?>
Przykład z życia wzięty
No i tu zaczynają się małe schody … Ze względu na specyfikę PHP (aplikacja „działa” raptem ułamki sekund) użyteczność tego wzorca jest nieco ogranicza w porównaniu z innymi językami (Java, C++ itp.). Jednak, mimo tego da się wykorzystać dobrodziejstwa Obserwatora w PHP.
<?php
class CacheObserver implements SplObserver {
public function update(SplSubject $subject) {
echo "Odswieza cache";
}
}
class RSSObserver implements SplObserver {
public function update(SplSubject $subject) {
echo "Odswieza RSS";
}
}
class NewsletterObserver implements SplObserver {
public function update(SplSubject $subject) {
echo "Wysylam maile z nowym newsem";
}
}
class News implements SplSubject {
private $observers = array();
public function attach(SplObserver $observer) {
$this->observers[spl_object_hash($observer)] = $observer;
}
public function detach(SplObserver $observer) {
unset($this->observers[spl_object_hash($observer)]);
}
public function notify() {
foreach ($this->observers as $observer) {
$observer->update($this);
}
}
public function add($data) {
echo 'Dodaje news do bazy';
$this->notify();
}
}
$news = new News();
$news->attach(new RSSObserver());
$news->attach(new CacheObserver());
$news->attach(new NewsletterObserver());
$news->add(array(
'title' => 'Tytuł',
'content' => 'blablabla'
));
?>
Do obiektu klasy News, który jest obserwowany dodajemy trzech obserwatorów. Dzięki temu zabiegowi przy dodawaniu nowego artykułu elementy systemu zostaną „poinformowane” i odświeżą dane w cache/RSS oraz wyślą odpowiednie maile do czytelników.
Zalety i wady
Zalety:
- Luźna zależność między obiektem obserwującym i obserwowanym. Ponieważ nie wiedzą one wiele o sobie nawzajem, mogą być niezależnie rozszerzane i rozbudowywane bez wpływu na drugą stronę.
- Relacja między obiektem obserwowanym a obserwatorem tworzona jest podczas wykonywania programu i może być dynamicznie zmieniana.
- Możliwość zablokowania klientowi drogi do bezpośredniego korzystania ze złożonego systemu, jeśli jest to konieczne.
Wady:
- Obserwatorzy nie znają innych obserwatorów, co w pewnych sytuacjach może wywołać trudne do znalezienia skutki uboczne.
Zastosowanie
Wzorzec Obserwatora sprawdza się wszędzie tam, gdzie stan jednego obiektu uzależniony jest od stanu drugiego obiektu.
Kanał ATOM


