Extended Observer-Pattern
Posted: August 3rd, 2008 | Categories: Actionscript 3.0, Design Patterns | 3 CommentsThe following post discusses an "extended" version of the Observer-Pattern.
The intent of the observer pattern is often described as an one-to-many dependency.
The key fact is that when one object changes its state, all listeners are notified about that change [GHJV95].
There are only two relevant kinds of objects in this pattern, observers and an observable.
An observable is basically an object that holds information on which other objects (observer) could be interested in.
When the data-state of the observable has changed the observers are notified about the change.
This kind of interaction is called publish-subscribe. The observable is the publisher of notifications. It sends out these notifications without having to know who its observers are[GHJV95].
So good so far...
Now let's examine the concrete implementation of an extended scenario.

The extended part in this observer pattern is the ISpecificObserver interface. If only specific notifications are interesting for an observer, it has to implement the ISpecificObserver interface and return an Array of notification interests (acceptedNotifications():Array).
Here are the interesting parts of the Observable:
public function addObserver( o: IObserver ): void { if( o is ISpecificObserver ) { var notifications: Array = ISpecificObserver( o ).acceptedNotifications(); var len: int = notifications.length; var list: ISet; while( --len > -1 ) { list = _specificObservers.getValue( notifications[ len ] ); if( list == null ) { list = new ArraySet(); _specificObservers.put( notifications[ len ], list ); } list.add( o ); } } else if( o is IObserver ) { _observers.add( o ); } }
public function notifyObservers( type: String = null, data: * = null ): void { var node: LinkedNode; if( type != null ) { var list: LinkedSet = LinkedSet( _specificObservers.getValue( type ) ); if( list != null ) { // -- notify all ISpecificObserver node = list.firstNode; while( ( node = node.post ) != null ) { ISpecificObserver( node.value ).update( this, type, data ); } } } else { type = DataNotificationType.GENERIC; } // -- notify all IObserver node = _observers.firstNode; while( ( node = node.post ) != null ) { IObserver( node.value ).update( this, type, data ); } }
An concrete implementation could look like this:
package { import com.addicted2flash.data.DataNotificationType; import com.addicted2flash.util.IObservable; import com.addicted2flash.util.ISpecificObserver; /** * @author Tim Richter */ public class ObserverExample implements ISpecificObserver { public function ObserverExample() { } public function acceptedNotifications(): Array { return [ DataNotificationType.COMPLETE ]; } public function update( observable: IObservable, type: String, data: * ): void { switch( type ) { case DataNotificationType.COMPLETE: // -- do something! break; } } } }
References:
[GHJV95] E. Gamma, R. Helm, R. Johnson, and J. Vlissides, Design Patterns – Elements of Reusable Object-Oriented Software, Addison-Wesley, 1995

[...] In this case it is recommended to use a more dynamic approach like an specific observable. [...]
[...] – Extended Observer-Pattern saved by kiyotin2009-05-13 – hounds, camera, sock saved by OkitaAoyagi2009-04-29 – Retreat saved by [...]
[...] searched for similar AS3 Observer implementation examples online and found but one. Hope my example helps your code find its way to clean & [...]