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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | 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 {} |
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.
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.