PHP Design Patterns .

PHP Design Patterns Observer

About the Observer

In the Observer pattern a subject object will notify an observer object if the subject's state changes.

In this example, the PatternSubject is the subject, and the PatternObserver is the observer. For the observer to be notified of changes in the subject it must first be registered with the subject using the attach method. For the observer to no longer be notified of changes in the subject it must be unregistered with the detatch method.

When the subject changes it calls the observer's update method with itself. The observer can then take the subject and use whatever methods have been made available for it to determine the subjects current state.

The Observer Pattern is often called Publish-Subscribe, where the subject would be the publisher, and the observer would be the subscriber.


AbstractObserver.php

//copyright Lawrence Truett and FluffyCat.com 2006, all rights reserved

include_once('AbstractSubject.php'); abstract class AbstractObserver {

abstract function update(AbstractSubject $subject_in);

}
To download source right-click here and "Save As...".

AbstractSubject.php

//copyright Lawrence Truett and FluffyCat.com 2006, all rights reserved

include_once('AbstractObserver.php');

abstract class AbstractSubject {

abstract function attach(AbstractObserver $observer_in); abstract function detach(AbstractObserver $observer_in);

abstract function notify();

}
To download source right-click here and "Save As...".

PatternObserver.php

//copyright Lawrence Truett and FluffyCat.com 2006, all rights reserved

include_once('AbstractObserver.php'); include_once('PatternSubject.php'); define('BR', '<'.'BR'.'>');

class PatternObserver extends AbstractObserver {

public function __construct() { }

public function update(AbstractSubject $subject) { echo BR.BR; echo '*IN PATTERN OBSERVER - NEW PATTERN GOSSIP ALERT*'.BR; echo ' new favorite patterns: '.$subject->getFavorites().BR; echo '*IN PATTERN OBSERVER - PATTERN GOSSIP ALERT OVER*'.BR; }

}
To download source right-click here and "Save As...".

PatternSubject.php

//copyright Lawrence Truett and FluffyCat.com 2006, all rights reserved

include_once('AbstractSubject.php'); include_once('PatternObserver.php');

class PatternSubject extends AbstractSubject {

private $favoritePatterns = NULL;

private $observers = array();

function __construct() { }

function attach(AbstractObserver $observer_in) { //could also use array_push($this->observers, $observer_in); $this->observers[] = $observer_in; }

function detach(AbstractObserver $observer_in) { //$key = array_search($this->observers, $observer_in); foreach($this->observers as $okey => $oval) { if ($oval == $observer_in) { unset($this->observers[$okey]); } } }

function notify() { foreach($this->observers as $obs) { $obs->update($this); } }

function updateFavorites($newFavorites) { $this->favorites = $newFavorites; $this->notify(); }

function getFavorites() { return $this->favorites; }

}
To download source right-click here and "Save As...".


testObserver.php

//copyright Lawrence Truett and FluffyCat.com 2006, all rights reserved

include_once('PatternSubject.php'); include_once('PatternObserver.php');

define('BR', '<'.'BR'.'>');

echo 'BEGIN TESTING OBSERVER PATTERN'.BR; echo BR;

$patternGossiper = new PatternSubject(); $patternGossipFan = new PatternObserver(); $patternGossiper->attach($patternGossipFan);

$patternGossiper->updateFavorites( 'abstract factory, decorator, visitor');

$patternGossiper->updateFavorites( 'abstract factory, observer, decorator'); $patternGossiper->detach($patternGossipFan);

$patternGossiper->updateFavorites( 'abstract factory, observer, paisley');

echo BR.BR; echo 'END TESTING OBSERVER PATTERN'.BR;
To download source right-click here and "Save As...".

output of testObserver.php

BEGIN TESTING OBSERVER PATTERN

*IN PATTERN OBSERVER - NEW PATTERN GOSSIP ALERT* new favorite patterns: abstract factory, decorator, visitor *IN PATTERN OBSERVER - PATTERN GOSSIP ALERT OVER*

*IN PATTERN OBSERVER - NEW PATTERN GOSSIP ALERT* new favorite patterns: abstract factory, observer, decorator *IN PATTERN OBSERVER - PATTERN GOSSIP ALERT OVER*

END TESTING OBSERVER PATTERN

References


Design Patterns
Design Patterns by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides

PHP 5
The Official PHP web site
Core PHP Programming, 3rd Edition by Leon Atkinson and Zeev Suraski
Comments Comments are left by visitors to FluffyCat.com and may or may not be accurate.
Comment by tungbk29 on 2015-11-19 Rate this Comment

In class PatternSubject -> function attach(), you should add argument. Becase when add 2 observer result $this->observers is //Array ( [0] => PatternObserver Object ( ) [1] => PatternObserver Object ( ))

I think
function detach(AbstractObserver $observer_in) {
foreach($this->observers as $okey => $oval) {
if ($oval->name == $observer_in->name) {
unset($this->observers[$okey]);
}
}
}

AND in class PatternObserver
public $name = '';
public function __construct($name) {
$this->name = $name;
}

Comment by prouty on 2014-07-23 Rate this Comment

In class PatternSubject -> function detach(), the arguments in array_search are in the incorrect order. It should be:

$key = array_search($observer_in, $this->observers);

(needle first, then haystack)

 
Sign in to comment on PHP Design Patterns Observer.