Archive for the ‘The rules’ Category

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.

1 Comment


Actionscript: The rules #1 – Refactor over reuse

Lately i’ve been trying to formalise a lot of the processes i use for coding actionscript so I started to write them down. I then was going to post them to my blog, however this quickly grew into a very large post, so i’ve decided to break them up into a series. Also this should make discussion of each of these points easier, and allow me to add more as i think of them (also it means i shouldnt be stuck for content for a while ;) ).

This isn’t a definitive list of best practices, and i’m sure people will disagree with me on some of the points but i think it helps to write this stuff down and discuss it. And with the introduction over it’s time to dive into the first rule.

“When creating classes don’t create them to be reused. Reusability should come from refactoring old classes”

This is an important but tricky skill to master, the ability to go back to some code you’ve already written and rework it. It can be a major headache the first time you want to reuse something, but if you can generalise a little more the code you’re useing every time you look at it, eventually you’ll end up with a solid code base. This goes hand in hand with not writing for reusability as raised by qlod, but rather letting reusablility come out of refactoring by itself.

Heres a simple example. Lets say we write a class for a specific task:

class myClass{
private var a:Number = 1
public function doSomethingWithNumbers():String{
//multiply by 2
a*=2.toString()
//then return the new value
return a
}
}

Later we want another class that does something similar. We could subclass our original like so:

class mySubClass extends myClass{
public function doSomethingWithNumbers():String{
//multiply by 2
a*=2
//then add 1
a+=1
//then return the new value
return a.toString()
}
}

However another approach is to move the common functionality to a super class, then have both classes extend this. First We create the super class:

class mySuperClass{
private var a:Number = 1
public function doSomethingWithNumbers():String{
return doSomethingSpecificWithNumbers().toString()
}
public function doSomethingSpecificWithNumbers():Number{
return a
}
}

Then we create our two sub classes:

class myFirstSubClass{
public function doSomethingSpecificWithNumbers():Number{
//multiply by 2
a*=2
//then return the new value
return a
}
}

And:

class mySecondSubClass{
public function doSomethingSpecificWithNumbers():Number{
//multiply by 2
a*=2
//then add 1
a+=1
//then return the new value
return a
}
}

So we now have two sub classes that do exactly what we wanted, and we also have a more generalised superclass, that should we want to create a third class in the future, is easy to extend for whatever we need it for.

I realise this may be an overly simplified example, but hopefully you’ll see the benefits of what i’m getting at here. Most importantly we’ve acheived reuse without having to waste time guessing what functionality we will need in the future while writing the first class. This means we’ve avoided writing any code that we don’t actually use, and anything that helps us to do less work can only be a good thing right?

2 Comments



  • SetPageWidth