Getting Started - part 2 - JObserver and JObservable

Have a programming question regarding your component, plug-in, extension or core hacks? Have an interesting tidbit, FAQ or programming tip you’d like to share? This is the place for you.

Moderators: tjay, seadap, Rogue4ngel, matthewhayashida

Post Reply
User avatar
jbruni
Joomla! Apprentice
Joomla! Apprentice
Posts: 37
Joined: Sat Oct 07, 2006 12:36 pm
Location: Uberlândia, MG, Brazil

Getting Started - part 2 - JObserver and JObservable

Post by jbruni » Sun Aug 19, 2007 2:15 am

Let´s continue our Image Base subpackage review.

We already saw Image JObject class defined in object.php, at Getting Started - JObject thread.

Now we´ll see Image JObserver class and Image JObservable class, both defined in observer.php

For this, one must study and understand well the Observer Pattern, because JObserver and JObservable implements this programming pattern.

[quote=∓quot;Wikipedia"\]Observer is a publish/subscribe pattern which allows a number of observer objects to see an event.[/quote]

Please read the Observer Pattern article at Wikipedia for more information.
(Another reference, that I haven´t read: Observer Pattern article at phpPatterns)

I think it is easy to understand the purpose of the Observer Pattern with the following example:

Code: Select all

<?php
$clock = new Clock;
$analogClock = new AnalogClock($clock);
$digitalClock = new DigitalClock($clock);
?>


In this example, Clock is descendant of the JObservable class, while AnalogClock and DigitalClock are descendants of the JObserver class.

$clock is the object that measures the time (the "quartzo"): it is the observable. Both $analogClock and $digitalClock are objects that display, in different ways, the time measured by $clock: they are the observers!

The JObserver and JObservable classes are the BASE for the Event Handler and Plug In mechanism that Joomla! has.

Event Handling concept should be well-known for most developers. The Observer Pattern is the programming pattern used behind an Event Handling mechanism.

Some references:
http://en.wikipedia.org/wiki/Event-driven_programming
http://en.wikipedia.org/wiki/Event_handler
Last edited by jbruni on Sun Aug 19, 2007 3:12 am, edited 1 time in total.

User avatar
jbruni
Joomla! Apprentice
Joomla! Apprentice
Posts: 37
Joined: Sat Oct 07, 2006 12:36 pm
Location: Uberlândia, MG, Brazil

Re: Getting Started - part 2 - JObserver and JObservable

Post by jbruni » Sun Aug 19, 2007 3:09 am

A JObserver observes and responds to a JObservable notification.

When you call JObserver constructor, instantiating an observer object, you should pass a JObservable instance as its parameter. This will make the link between the JObserver and its JObservable object:

$observer = new JObserver($observable);

(in our previous example, $analogClock was an observer, while $clock was observable)

If you are curious as me, take a look at the JObserver source code, without most comments:

Code: Select all

<?php
// Abstract observer class to implement the observer design pattern

class JObserver extends JObject {

   var $_subject = null; // Event object to observe

   function __construct(& $subject)
   {
      // Register the observer ($this) so we can be notified
      $subject->attach($this);

      // Set the subject to observe
      $this->_subject = & $subject;
   }

    // Method to update the state of observable objects
   function update() {
      return JError::raiseError('9', 'JObserver::update: Method not implemented', 'This method should be implemented in a child class');
   }
}
?>


What do we see? First, there is a private property, $_subject, that will retain a reference to the observable object that the observer will observe. This reference comes from the parameter passed to the constructor ($subject, that must be JObservable).

Also, we see in the constructor a call to
$subject->attach($this);
meaning that the observer ($this), will be attached to the JObservable list of observers (as we will see soon).

And that is all! One must understand that this is an abstraction class. It must me extended to be usable. Those classes provides the core mechanism to possible amazing features, allowing them to be avaiable. I hope everyone can understand this well. It is like spiritual discipline: the results come very after.

There is one more thing to look at the JObserver class. It is the update method. As it will be called from the JObservable in its notify method (when observable is notifying its observers about the occurrence of an event), it must be declared, even if its functionality will be given only in the descendant classes. That´s what is called interface. Although update has no real function in the base class, we have an interface for communication between observer and observable already defined and activated - doesn´t matter who will be observing and observed in fact. (It can be any Plug In...)
Last edited by jbruni on Sun Aug 19, 2007 3:16 am, edited 1 time in total.

User avatar
jbruni
Joomla! Apprentice
Joomla! Apprentice
Posts: 37
Joined: Sat Oct 07, 2006 12:36 pm
Location: Uberlândia, MG, Brazil

Re: Getting Started - part 2 - JObserver and JObservable

Post by jbruni » Sun Aug 19, 2007 3:22 am

It was a joy for me to write for you again. I hope it helps. Joomla! is big... this is the tip of the iceberg... But I won´t think about that!  :P

Time to go to bed. I shall continue tomorrow.

:laugh: May every beings in all worlds be happy and joyfull! :)

User avatar
jbruni
Joomla! Apprentice
Joomla! Apprentice
Posts: 37
Joined: Sat Oct 07, 2006 12:36 pm
Location: Uberlândia, MG, Brazil

Re: Getting Started - part 2 - JObserver and JObservable

Post by jbruni » Sun Aug 19, 2007 2:01 pm

Now you understood brightly the power that underlies those interesting JObserver and JObservable classes, let´s take a look at the Image JObservable class!

Code: Select all

<?php

class JObservable extends JObject
{
   var $_observers = array(); // An array of Observer objects to notify
   var $_state = null; // The state of the observable object

   function __construct() {
      $this->_observers = array();
   }

   // Get the state of the JObservable object
   function getState() {
      return $this->_state;
   }

   // ...we will see the other methods one by one... (jbruni's note)
}

?>


There are two private properties: $_observers and $_state

$_observers is an array of attached JObservers that JObservable will notify when some notifyable thing happens.

As you studied about the Observer Pattern, one observable can be observed by many observers.

$_state will, like a flag, signalize the state of the observable object.
It should be accessed through the getState method:
$observable->getState();

JObservable constructor
simply initializes the $_observers list as an empty array.

Now, there are only three more methods, that provides the linking and communication between JObservable and its JObservers:
- attach - to attach an observer object
- detach - to detach an oberver object
- notify - to "spread the news", it means, to notify the observers about the occurence of an event (for example: the clock would notify a time change every second)

Let´s see the attach method:

Code: Select all

<?php

   // Attach an observer object
   function attach( &$observer)
   {
      // Make sure we haven't already attached this object as an observer
      if (is_object($observer))
      {
         $class = get_class($observer);
         foreach ($this->_observers as $check) {
            if (is_a($check, $class)) {
               return;
            }
         }
         $this->_observers[] =& $observer;
      } else {
         $this->_observers[] =& $observer;
      }
   }

?>


The key of the attach method is the line that adds the observer object to the observable´s list of observers:
$this->_observers[] =& $observer;

From the rest of the attach method code, one can deduce that a JObservable object can only have ONE observer of a single class. It means: although it can have many observers, each one must be from a different class; they can´t be instances from the same class.
Image Is it correct? May some core team member confirm this to us, 101s?

The detach method is quite simple - it detaches an observer from an observable, and returns true if the operation is successfull.

Code: Select all

<?php

   // Detach an observer object
   function detach( $observer)
   {
      // Initialize variables
      $retval = false;

      $key = array_search($observer, $this->_observers);

      if ( $key !== false )
      {
         unset($this->_observers[$key]);
         $retval = true;
      }
      return $retval;
   }

?>


So, it´s easy to attach a JObserver to a JObservable:
$observable->attach($observer);
(but this is done inside the observer constructor - normally you will not need to call it directly)

And it´s easy to detach a JObserver from a JObservable:
$observable->detach($observer);

Finally, the key for the whole behaviour of the Observer Pattern: the JObservable notify method!

Code: Select all

<?php

   // Update each attached observer object and return an array of their return values
   function notify()
   {
      // Iterate through the _observers array
      foreach ($this->_observers as $observer) {
         $return[] = $observer->update();
      }
      return $return;
   }

?>


A call to
$observable->notify();
will call all observable´s observers update method.
(And, also return an array of the update's return values.)

So, it is in the update method of JObserver descendant that you will write the code that will respond to the notification of an event coming from the JObservable. And, of course, you will call the JObservable descendant notify method when something you want to notify happens in the JObservable object.

And we are done with our part 2!

Let´s remember that both JObserver and JObservable are JObject descendants. So, both inherits all properties and methods we saw when studying the JObject class.

And a final reminder: the term "listener" is sometimes used instead of "observer" (as in Flash's ActionScript "EventListener")
Last edited by jbruni on Sun Aug 19, 2007 2:34 pm, edited 1 time in total.

User avatar
jbruni
Joomla! Apprentice
Joomla! Apprentice
Posts: 37
Joined: Sat Oct 07, 2006 12:36 pm
Location: Uberlândia, MG, Brazil

Re: Getting Started - part 2 - JObserver and JObservable

Post by jbruni » Sun Aug 19, 2007 2:06 pm

Image

User avatar
jbruni
Joomla! Apprentice
Joomla! Apprentice
Posts: 37
Joined: Sat Oct 07, 2006 12:36 pm
Location: Uberlândia, MG, Brazil

Re: Getting Started - part 2 - JObserver and JObservable

Post by jbruni » Sun Aug 19, 2007 2:19 pm

Well... I am trying to do my best, but please warn me if something is incorrect in this "Getting Started" series!

Any other comment or advice is welcome.

Thank you!

:)

User avatar
AmyStephen
Joomla! Guru
Joomla! Guru
Posts: 579
Joined: Wed Nov 22, 2006 3:35 pm
Location: Nebraska
Contact:

Re: Getting Started - part 2 - JObserver and JObservable

Post by AmyStephen » Mon Aug 20, 2007 12:22 am

We are starting to assemble the Wiki and nearly to the point of getting you to port your examples (or helping you do that) to the Wiki. Have *NOT* forgotten about you - you are still doing fabulous and important work! THANKS!
~*~ Joomla!'s Queen of the Blues - Jennifer Marriott ~*~
http://OpenSourceCommunity.org/node/1719/

User avatar
seadap
Joomla! Intern
Joomla! Intern
Posts: 95
Joined: Mon Dec 04, 2006 12:22 am
Contact:

Re: Getting Started - part 2 - JObserver and JObservable

Post by seadap » Mon Aug 20, 2007 4:38 am

Here here.  Nice work jbruni.  Can't wait to take advantage of your efforts!  I know you will be saving me(us) some serious effort!
Knowledge is realizing that the street is one-way, wisdom is looking both directions anyway.

User avatar
Batch1211
Joomla! Fledgling
Joomla! Fledgling
Posts: 3
Joined: Sat Sep 02, 2006 6:11 pm

Re: Getting Started - part 2 - JObserver and JObservable

Post by Batch1211 » Tue Sep 04, 2007 9:37 am

Thanks,

this is wonderful. I would be really thankful, if you'd find the time to carry on...

Best wishes.


Post Reply