Design Pattern – Observer

Posted on April 1, 2014, 4:00 pm by about-dev.com


The problem:
Well, this is my favorite. Why? Because get you free of a lot of responsabilities. Let me explain: suppose you have an online newspaper website and for publishing an article you must follow these steps:
1. write the article
2. insert the article in the proper table in your database
3. delete the cache (an necessary operation for the article to appear on the page)
4. display the article in the proper page
5. and what ever action you think of, necessary for this type of context

I think you’ve noticed that this is a representation of a one to many relationship. One object changes it’s state and all his dependencies must be notified to act proper.

It’s a lot of work to do and for things to work properly you must follow them ad literam. By the way if you want to update an article you’ll be forced to follow the same steps. Annoying, I would dare to say.

Using the old fashion style of procedural code you would probably define some functions to do these operations and you’ll try to stay very focused to not miss a thing, because if something go wrong the result will be a disaster. In object oriented style I would use the wonderful Observer design pattern, which consists of 2 essential parts:
- an Observable object (usually called the Subject)
- and an Observer object

Let’s see what’s the deal with these two objects and what’s their role or the main difference between them.

The role of the Observer is to keep track of all the changes produced over the Subject and to make all the necessary changes. That’s why all the observers needed are registered (attached or added) in the Subject and when a subject changes it’s state must notify the observer about that. Let’s see the structure of these two objects:

class Observer implements SplObserver {
 ………………………………………………………………………………………………
 public function update(SplSubject $object){
  //things to do
 }
}
class Subject implements SplSubject {
 private $_observers = array();
………………………………………………………………………………………………………
  
 //Add an observer
 public function attach(SplObserver $observer) {
  $this->_ observers[] = $observer;
 }
  
 //Remove an observer
 public function detach(SplObserver $observer) {
  foreach ($this->_observers as $key => $obj) {
   if ($obj == $observer) {
    unset($this->_observers[$key]);
   }
  }
 }
  
 //Notificate an observer
 public function notify(){
  foreach ($this->_observers as $observer){
   $observer->update($this);
  }
 }
  ………………………………………………………………………………………………………
}

You can see that all the methods needed are quite simple and self explanatory.

The solution (implementation):
Example of procedural code:

//index.php – suppose that we have already established a database connection and selected the proper database
if(!empty($_POST[‘send_article’])){
   $id = insert_article($_POST);
   if(!empty($id)){
     delete_article_cache($id);
     display_article($id);
   }else{
      echo "Some error occurred!"; 
   }
}
//functions.php – suppose that we have already established a database connection
function delete_article_cahce(){
 //some code
}
 
function display_article(){
 //some code
}

Example of object oriented code:
OBS: In our case the Observer is the Article and the Subject is the Newspapper.

class Article implements SplObserver{
 private $_id;
 private $_title;
 private $_description;
 
 public function __construct($id, $title, $description){
        $this->_id   = $id;
        $this->_title   = $title;
        $this->_description  = $description;
 }
 
 public function update(SplSubject $obj){
        $obj->insert_article();
        $obj->delete_article_cache();
         $obj->display_article();
 }
}
class Newspapper implements SplSubject{
 private $_observers = array();
 private $_name;
 
 public function __construct($name){
  $this->_name = $name;
        }
 
 public function attach(SplObserver $observer){
  $this->_observers = $observer;
 }
 
 public function detach(SplObserver $observer){
   foreach($this->_observers as $key=>$obj){
      if($obj == $observer){
         unset($this->_observers[$key]);
      }
   }
 } 
 
 public function notify(){
   foreach($this->_observers as $observer){
       $observer->update($this);
   }
 }
 
 public function insert_article(){
    //some code here
 }
 
 public function delete_article_cache(){
    //some code here
 }
 
 public function display_article(){
    //some code here
 }
}
$newspapper = new Newspapper(“One_newspapper”);
$article = new Article(‘1’, ‘Cucu bau’, ‘Some description for Cucu bau’);
$newspapper->attach($article); //include observers in the Subject (ak the Newspapper object)

Now the Article and Newspaper objects are connected and whatever change occurs with the subject, the observers will take care of everything. Nice.

Related articles:


Leave a Comment:

User
Email
Website

Blog Search

Popular Blog Categories

Newsletter

Want to be informed about latest posts? Subscribe to our newsletter