The Observer Pattern: OOP Techniques in PHP

Posted on 09. Mar, 2009 by Will Fitch in PHP

The observer pattern provides another way to maintain loose coupling within your code. It’s an extremely simple pattern and is implemented similarly across languages. There are two parts: the observer and the observable object. Let’s address them both starting with the observer.

The Observer

PHP
  1. <?php
  2. interface IObserver
  3. {
  4.         /**
  5.          * Method called on event change
  6.          *
  7.          * @param mixed $sender
  8.          * @param mixed $args
  9.          */
  10.         public function onChange($sender, $args);
  11. }
  12. ?>

As you can see from above, the observer implements a single method called onChange. This method is executed when the observable class changes. The first parameter is typically the instance of the class changing and the second arguments relative to the change. Now let’s look at the IObservable interface:

The Observable Object

PHP
  1. <?php
  2. interface IObserverable
  3. {
  4.         /**
  5.          * Add an observer
  6.          *
  7.          * @param mixed $obj
  8.          */
  9.         public function addObserver($obj);
  10. }
  11. ?>

The observable class provides a method for one or more observers to be notified. The observable class needs to maintain a list of these observers and notify them when necessary. A common usage of this is a logging mechanism that needs to be notified when data is created, updated and deleted.

PHP
  1. <?php
  2.  
  3. class UserLogging implements IObserver
  4. {
  5.                
  6.         public function onChange($sender, $args)
  7.         {
  8.                 // Log the changes (we echo here)
  9.                 echo ‘The class is ‘.get_class($sender).‘ and the arguments are ‘.print_r($args,1);
  10.         }
  11. }
  12.  
  13. class User implements IObserverable
  14. {
  15.         private $_observers=array();
  16.        
  17.         private function notifyObservers($args)
  18.         {
  19.                 for ($i=0, $count=count($this->_observers);
  20.                          $i < $count; $i++)
  21.                 {
  22.                         $this->_observers[$i]->onChange($this, $args);
  23.                 }
  24.         }
  25.        
  26.         public function deleteUser($id)
  27.         {
  28.                 $db->deleteUser($id);
  29.                 $this->notifyObservers(array(‘user_id’=>$id));
  30.         }
  31.        
  32.         public function addObserver($obj)
  33.         {
  34.                 // Add logic for interface implementation check here if you want.
  35.                 $this->_observers[] = $obj;
  36.         }
  37. }
  38.  
  39. $user = new User();
  40. $user->addObserver(new UserLogging());
  41. $user->deleteUser(55);
  42. ?>

Not only does this provide you some pseudo event access, but this is a much cleaner, maintainable implementation of observing a particular object.

Conclusion

I hope you find ways at work to implement this use pattern. We more often than not get caught up with getting code written (it comes with the territory) and lose sight of these power and proven designs to get the job done. I’m certainly just as much to blame as the next developer! Hope this helps!

Tags: , , ,

Related Articles

Leave a Reply