The Observer Pattern: OOP Techniques 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
interface IObserver
{
	/**
	 * Method called on event change
	 *
	 * @param mixed $sender
	 * @param mixed $args
	 */
	public function onChange($sender, $args);
}
?>

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
interface IObserverable
{
	/**
	 * Add an observer
	 *
	 * @param mixed $obj
	 */
	public function addObserver($obj);
}
?>

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
 
class UserLogging implements IObserver
{
 
	public function onChange($sender, $args)
	{
		// Log the changes (we echo here)
		echo 'The class is '.get_class($sender).' and the arguments are '.print_r($args,1);
	}
}
 
class User implements IObserverable
{
	private $_observers=array();
 
	private function notifyObservers($args)
	{
		for ($i=0, $count=count($this->_observers);
			 $i < $count; $i++)
		{
			$this->_observers[$i]->onChange($this, $args);
		}
	}
 
	public function deleteUser($id)
	{
		$db->deleteUser($id);
		$this->notifyObservers(array('user_id'=>$id));
	}
 
	public function addObserver($obj)
	{
		// Add logic for interface implementation check here if you want.
		$this->_observers[] = $obj;
	}
}
 
$user = new User();
$user->addObserver(new UserLogging());
$user->deleteUser(55);
?>

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!

Mega World News Facebook Twitter Myspace Friendfeed Technorati del.icio.us Digg Google Yahoo Buzz StumbleUpon Weekend Joy

TAGS:  , , ,

Leave a Reply