AS3 Singleton Pattern Implementation
Many times when developing you will find that your application calls for a single instance of a class to manage a specific service across the system. For example, let’s say that your application needs to have one single instance of a class that manages all events within the system. Or another scenario could be where the application calls for a single instance of a class to manage all WSDL calls across the system. In order to support the required functionality for the application you would need to create a class that implements what is known as the Singleton design pattern.
The Singleton pattern is implemented by creating a class that has a static public method which instantiates a new instance of the object if one does not exist. If an instance already exists, it simply returns a reference to that object which is a static property of the class, typically named ‘instance’. A best practice naming convention for this method is ‘getInstance();’. To make sure that the object cannot be instantiated in any other way, the constructor is made either private or protected. A Singleton is also considered to be an anti-pattern to some extent as it can be used as a euphemism for a global variable. However, in Object Oriented Programming it is an extreamly useful tool when used correctly.
As I mentioned earlier, the constructor for a Singleton is made either private or protected to restrict it’s access from being instantiated. Since constructors can only be declared as public in ActionScript 3 this is not allowed. A common solution to this is to simply add a inner class within the same file as the class definition and pass an instance of the private class as an argument to the constructor. This way only the getInstance(); method has access to the private class. The only problem with this approach is that the constructor can be called from anywhere within the application with a null value passed in as the argument to the constructor. My solution to this is simple, check that the parameter passed to the constructor is not null. This is how a true Singleton implementation is achieved. The only time that this will not work is if the singleton class is a sub class and the constructor needs to make a call to super. The reason that this will not work is that a call to a super classes constructor must be executed in the very first line of code, therefore a parameter value can not be validated.
Below I have added a simple example demonstrating how to implement the Singleton pattern in ActionScript 3.0:
package
{
public final class Singleton
{
/**
* Defines the unique instance of the class
*/
private static var instance:Singleton;
/**
*
* Singleton constructor which is never to be directly
* instantiated
*
* @param Inner class which restricts constructor
* access to private
*
*/
public function Singleton(access:Private)
{
if (access == null)
{
throw new Error("Singleton Exception…");
}
instance = this;
}
/**
*
* All calls to a Singleton are to be made via
* Singleton.getInstance(); in order to retrieve
* the singleton instance of the Singleton
*
* @return the Singleton of the class
*
*/
public static function getInstance() : Singleton
{
if (instance == null)
{
instance = new Singleton( new Private() );
}
return instance;
}
}
}
/**
* Inner class which restricts constructor access to private
*/
final class Private {}
August 6th, 2007 at 11:11 am
Hi Eric,
Great post you have got there. Thank you! I am learning flex and actionscript3 currently, and I was a bit surprised to know, I could not mark constructors as private.
There is another option though, that avoids the need to create an extra internal class. You can simply put a static boolean flag inside the singleton, and let the constructor fail, if the flag is false. The static getInstance() method can then set and reset this flag on instance creation.
I have shown how here, in my post on ActionScript3 Singleton.
August 7th, 2007 at 7:09 am
Hey Polesen,
You have a nice solutions as well, however I prefer to have an inner class which sole purpose is to restrict constructor access to private as I find this method to be an elegant solution as it allows an abstraction of singleton creation from Singleton implementation.
A Singleton class in my opinion should not contain any members (static or instance) which are responsible for creating the singleton object other than the static instance member.