Actionscript: The rules #2 – Observer pattern for all events

All classes that generate events should do so via the observer pattern.

This one might prove a little more contravertial than the last, but i’m going to stick my neck out and say that all classes should use the observer pattern for events, rather than myEvent=function() callbacks, or object listeners.

For those who don’t want to read up about the observer pattern check out the EventDispatcher class which is basically an implementation of this. or better still grant skinners GDispatcher which has a few extra tricks up its sleeve. The first benefit of this method is that you can have multiple objects listening to the same event. This is all covered in the chapter on the observer pattern in Colin Moocks Essential ActionScript 2. If you want to start using these classes i suggest you read the tutorials on EventDispatcher and Delegate over at actionscript.org.

I also tend to use Dynamic flash’s Delegate class rather than macromedias own for scoping the listener object, as this also has a few added extras, such as passing the delegate itself to a listening function, as well as the event object, which makes removal of anonymous delegates an easy task.

This may sound like overkill for a lot of simple class structures, and you will have to remember to remove your event listeners, but it does mean consistency. If you’re using EventDispatcher in one class, and myEvent=function() style callbacks in another, then it’s easier to make mistakes. And harder to pick up code that you havent looked at in a while, because you have to figure out which method you used.

When using EventDispatcher it’s always useful to include static constant variable strings (try saying that 10 times quickly) for all the events a class will dispatch. This not only lets you keep track of which events a class broadcasts easily, but also provides compile time checking to make sure you are subscribing to events that actually exist. For example:

import com.gskinner.event.GDispatcher
class com.lookmum.Broadcaster{
public static var MYEVENT:String = 'myEvent'
public var addEventListener:Function
public var removeEventListener:Function
public var dispatchEvent:Function
public function Broadcaster(){
GDispatcher.initialize(this)
}
public function myFunction(){
this.dispatchEvent({type:MYEVENT,target:this})
}
}

and…

import com.lookmum.Broadcaster
import com.dynamicflash.utils.Delegate
class com.lookmum.Observer{
private var broadcaster:Broadcaster
public function Observer(){
this.broadcaster = new Broadcaster
this.broadcaster.addEventListener(Broadcaster.MYEVENT, Delegate.create(this, this.eventHandler))
}
public function myFunction(){
this.broadcaster.myFunction()
}
private function eventHandler(){
trace('event handled')
}
}

Two added benefits are that this makes it easy to document events because you can attach javadoc comments to the string constants and they stand out from other class members so events are easy to find rather than function callbacks which apart from their names look just like empty functions.

This is all very similar to the way events are used in AS3 and so if you can get used to using this methodology now, then the transition should be that much easier. In fact another useful methodology that AS3 uses is the use of a proper Event class, as the event object rather than using a standard object, which makes it easier to keep track of what properties your event object will hold.

Comments are closed.


  • SetPageWidth