Wzorzec observer należy do wzorców czynnościowych. W praktyce umożliwia on powiadamianie obiektów (obserwatorów) o zmianie danych obiektu czy klasy centralnej (obserwowanej) dając możliwość wielokrotnego wykorzystywania klas bez zbędnych modyfikacji ich kodu czyniąc go przy tym czytelniejszym i bardziej przejrzystym.

Aby pokazać działanie wzorca observer posłużę się prostym przykładem. Załóżmy, że mamy klasę modyfikującą dane w bazie i chcemy aby w momencie zapisu zmienionych danych został utworzony plik z cachem zawierającym nowe dane oraz aby informacja o tych zmianach trafiła do administratora.
Zacznę od stworzenia interfejsu dla obiektów obserwatorów, który zawierać będzie definicje metody update:

PHP:
  1. interface IObserver
  2. {
  3.     function update();
  4. }

Następnie stworzę 2 klasy obserwatorów implementujące powyższy interfejs, jedna odpowiedzialna będzie za utworzenie nowego cache'u a druga za powiadomienie admina o zmianach:

PHP:
  1. class CacheObserver implements IObserver
  2. {
  3.     /**
  4.      * Metoda zapisuje nowe dane do cache
  5.      */
  6.     function update()
  7.     {
  8.         // zapis danych do cache
  9.         // [...]
  10.     }
  11. }
  12.  
  13. class MailObserver implements IObserver
  14. {
  15.     /**
  16.      * Metoda wysyla maila do admina
  17.      */
  18.     function update()
  19.     {
  20.         // wyslanie maila do admina
  21.         // [...]
  22.     }
  23. }

Mając już obserwatorów utworzę klasę centralną (obserwowaną) czyli w naszym przykładzie modyfikującą dane osoby w bazie:

PHP:
  1. class ModifyObservable
  2. {
  3.     /**
  4.      * Tablica obserwatorow
  5.      *
  6.      * @var array
  7.      * @access private
  8.      */
  9.     private $_observers = array();
  10.  
  11.     /**
  12.      * Metoda dodaje obserwatora
  13.      *
  14.      * @param object Obiekt obserwatora
  15.      */
  16.     function addObserver($observer)
  17.     {
  18.         $this->_observers[] = $observer;
  19.     }
  20.    
  21.     /**
  22.      * Metoda powiadamia swoich obserwatorow o uaktualnieniu
  23.      */
  24.     function notify()
  25.     {
  26.         foreach($this->_observers as $observer) {
  27.             $observer->update();
  28.         }
  29.     }
  30.    
  31.     /**
  32.      * Metoda dokonuje modyfikacji danych
  33.      */
  34.     function update()
  35.     {
  36.         // modyfikacja danych
  37.         // [...]
  38.  
  39.         // powiadomienie obserwatorow
  40.         $this->notify();
  41.     }
  42. }

Metoda update() w klasie Modify aktualizuje dane oraz wywołuje metodę notify(), która to poprzez cykliczne wywołanie metod update() swoich obserwatorów (CacheObserver i MailObserver)

PHP:
  1. $modify = new ModifyObservable();
  2. $modify->addObserver(new CacheObserver());
  3. $modify->addObserver(new MailObserver());
  4. $modify->update();

Jak więc widać wzorzec ten jest dość prosty w implementacji i daje nam wymierne korzyści takie jak możliwość wielokrotnego wykorzystywania klas bez zbędnych modyfikacji kodu, unikanie trwałych i sztywnych zależności między klasami, czytelny i przejrzysty kod.

Więcej na temat wzorca observer:
http://pl.wikipedia.org/wiki/Wzorzec_obserwatora
http://4programmers.net/PHP/Wzorce_Projektowe#id-Obserwator
http://www.phppatterns.com/docs/design/observer_pattern
http://www.fluffycat.com/PHP-Design-Patterns/Observer/
http://www.vincehuston.org/dp/observer.html

Leave a Reply

You must be logged in to post a comment.