AS3: Singletons
----------------------
AS3: Main
----------------------
Prerequisite reading: AS3: Static Keyword, The by Diki
----------------------
Source file(s): MySingletonClass.as
----------------------
As previously explained, the static keyword can be used to create properties on objects that only exist once for all instances of that object. But what if we wanted to create an object than only exists once across our ActionScript project?
This is where the singleton design pattern come into play. A singleton is an object that can only be initialised once in your entire project. This is done by creating a static variable the same type of your class and a static function to return that variable:
package {
public class MySingletonClass {
private static var _this:MySingletonClass;
public function MySingletonClass() {
}
public static function getInstance():MySingletonClass {
if (_this == null){
_this = new MySingletonClass();
}
return _this;
}
}
}
The above code creates a static variable of type MySingletonClass on the MySingletonClass Object and the getInstance static function returns it. That means where ever we write MySingletonClass.getInstance() it will always return the same MySingletonClass object.
We can then add non static variables and functions to the MySingletonClass, like this:
package {
import flash.utils.getQualifiedClassName;
public class MySingletonClass {
private static var _this:MySingletonClass;
private var myVar:String = "Hello World";
public function MySingletonClass() {
}
public static function getInstance():MySingletonClass {
if (_this == null){
_this = new MySingletonClass();
}
return _this;
}
public function getVar():String {
return myVar;
}
}
}
This means we can say MySingletonClass.getInstance().getVar() and the output will be "Hello World". We could create a number of non static properties, write getters & setters for them, and using MySingletonClass.getInstance() modify their values.
One small problem at the moment is that we could create new instances of MySingletonClass which would invalidate the singleton design pattern. We can prevent this by adding a simple error check, to see if _this has been initiated, into the constructor:
public function MySingletonClass() {
if (_this == null) {
_this = this;
}else {
throw new Error(getQualifiedClassName(this) + " is a singleton, use getInstance() instead.");
}
}
It is important to think long and hard before choosing to use the Singleton design pattern, as it is often over used and used incorrectly. Due to a singleton's global scope it is an easy trap to fall into to want to use it extensively.
Singletons should be used when only one instance of an object is required (i.e. more than one instance of said object would causes errors) and that object needs global scope. I often use a singleton for managing my sounds, as I only want one sound object (as multiple sounds playing over the top of each other would sound bad) and I want to play sounds from anywhere.
There are a number of other design patterns (e.g. Decorator, MVC, etc) all of which have their own pros and cons, the more you have a (at least cursory) knowledge of, the better you'll be able to decide on the right tools for the job.