Now
you understood brightly the power that underlies those interesting
JObserver and
JObservable classes, let´s take a look at the
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.
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")