Observer Pattern Actionscript 3

One of the most useful design pattern when you don’t want to work with framework like Swiz, Cairngorm, Mate or PureMVC but you’d like to work with a comfortable utility to manage events in your application or web site is Observer Pattern.

The definition from Wikipedia is:

The observer pattern (a subset of the publish/subscribe pattern) is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event handling systems.


For more information and if you want to see UML diagram, take a look at wikipedia site.

You can use this design pattern when you want to notify to all object that are interesting in a particular notification; for example if you have 100 buttons you can show or hide only even or odd ones; it’s not important where they are added, if in the same displaylist or in another one, because it’s observer pattern that substitute event handling to notify something.
If you think how you usually work with event handling you must know where is situated your component  and if it’s nested in 10 different containers you must dispatch that event trough each component… it’s totally crazy!

Observer Pattern solve this problem because it’s like an event engine where knows all object that could be interesting in a notification and it notifies to all components.
When you start to work with it, you could use everywhere in your productions, believe me!

So how Observer Pattern works:

First of all you must create an Interface (IObserver) that has an update method that will be called from Observer manager when a notification will be called:

public interface IObserver {
    function update(_notification:String):void;
}
Then you must have an Observer Manager that manage all objects that implements IObserver interface.
This manager will have 3 public methods: subscribe, unsubscribe and notify.
You call subscribe when you want to add an object that is update from Observer; unsubscribe when you remove an object from a displaylist or if you don’t need to update anymore  and notify when you want to notify something to all subscribed objects:
public class ObserverManager {
private static var instance : ObserverManager;
private var observerData : Array;
public function ObserverManager():void{
observerData = new Array();
}
public static function getInstance() : ObserverManager{
if(instance == null)
instance = new ObserverManager();
return instance;
}
public function subscribe(observer:IObserver):void{
observerData.push(observer);
}
public function unsubscribe(observer : IObserver) : void {
var totObs:int = observerData.length;
for(var i:int = 0; i < totObs; i++){
if(observer === observerData[i]){
observerData.splice(i, 1);
break;
}
}
}
              
       public function notify(_notification:String):void{
var totObs:int = observerData.length;
for(var i:int = 0; i < totObs; i++){
observerData[i].update(_notification);
}
}
}

Ok now you are ready to work with observer, so we create an object that implements IObserver and another one that add on displaylist all IObserver objects and notify to all some notifications:

custom button that implements IObserver interface:

public class ObserverButton extends Button implements IObserver

{

	public static const HIDE_BUTTON:String = "hideBtnEvt";

	public static const SHOW_BUTTON:String = "showBtnEvt";

		

	public function ObserverButton()

	{

		super();			

	}

		

	public function update(_notification:String):void

	{	

		switch(_notification){			

			case HIDE_BUTTON:

				this.alpha = .2;

				break;

				

			case SHOW_BUTTON:

				this.alpha = 1;

				break;

		}			

	}

}

subscribe some custom buttons to observer manager:			

protected var observer:ObserverManager;

protected function init():void{				

	observer = ObserverManager.getInstance();

	for(var i:int = 0; i < 100; i++){			

		var btn:ObserverButton = new ObserverButton();

		btn.label = i.toString()

		addElement(btn);




		if((i & 1) == 0)

			observer.subscribe(btn);

					

		btn.x = Math.random() * 800;

		btn.y = Math.random() * 500 + 70;

					

}

That’s it! You can see the Flex 4 sample that use Observer Pattern here (with right click you can see and download source code).
If you have any questions or suggestions feel free to leave a comment.

Advertisements

6 thoughts on “Observer Pattern Actionscript 3

  1. I like your example, i always found myself wonder why this pattern when you can make use of event handling. but i think is a lot more simple and helps solve other effects such as event bubbling. the more i read about mobile development, the more i hear make your applications lite, it may be this is a good approach instead of registering and unregistering events. I also think observer pattern can filter as well who can be notify and who doesn’t upon an update.

  2. I don’t really get your comment about event handling that requires you to know where the component is situated. It appears to me that event handling is the same as observer.
    ObserverManager here can extend EventDispatcher:
    public class ObserverManager extends EventDispatcher{
    public function notify(_notification:String):void{
    dispatchEvent(new Event(_notification));
    }
    }

    And instead of calling observer.subscribe(btn), we can call
    observer.addEventListener(ObserverButton.HIDE_BUTTON, btn.update);
    observer.addEventListener(ObserverButton.SHOW_BUTTON, btn.update);

    In the method update(e:Event), we can also get back the event string as e.event

    I agree that your observer implementation has the best performance. But I also believe Flash can manage event handling well and shouldn’t bring much overhead to the application.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s