In this Quick Tip we are going to talk about the Singleton design pattern and how it can help you to optimize your code when you need exactly one instance of a class.
Step 1: Introduction
As a programmer you must be aware that there are some cases where you want to use an instance of a class, but you want to create just one and keep it throughout the entire program. Well, that’s what Singletons are for.
Step 2: What is a Singleton?
A Singleton is a Object-Oriented Design Pattern used by many programmers; it lets you create a sort of “global” instance of a class. It is created in such a way that only one unique instance can exist, so that all instances of that class are in exactly the same state.
Step 3: Why Would We Use it?
The most common example would be a score – for example a football score. You would have a Score class, with properties homeTeamScore and awayTeamScore and a method like increaseScore(team:Team).
Both teams must be able to increase their score when they make a goal, but you can’t give each team their own Score instance; you want both to access and modify the same one.
This is a case where a Singleton is a perfect solution, since it could work as a global instance that anybody can access; you will have just one instance for everyone, so you don’t have to worry that each team will be modifying a different score.
Step 4: Singleton Class
Now let’s start creating a singleton in AS3, but first remember the key elements of a singleton:
- Anyone must be able to access it.
- Just one instance can be created.
Create a new AS3 class and call it Singleton.as.
(Not familiar with class-based coding? Check out this quick intro.)
Here’s the basic Singleton code:
package { public class Singleton { private static var instance:Singleton; //This will be the unique instance created by the class private static var isOkayToCreate:Boolean=false; //This variable will help us to determine whether the instance can be created public function Singleton() { //If we can't create an instance, throw an error so no instance is created if(!isOkayToCreate) throw new Error(this + " is a Singleton. Access using getInstance()"); } //With this method we will create and access the instance of the method public static function getInstance():Singleton { //If there's no instance, create it if (!instance) { //Allow the creation of the instance, and after it is created, stop any more from being created isOkayToCreate = true; instance = new Singleton(); isOkayToCreate = false; trace("Singleton instance created!"); } return instance; } } }
Step 5: Create a Flash Project
Now let’s go and test the Singleton, first create a new Flash file named Main.fla. On the properties panel set the class also to Main.
Step 6: Create a Singleton
Create a new class named “Main” and create an instance of Singleton using the constructor:
package { import flash.display.MovieClip; public class Main extends MovieClip { public function Main() { var testSingleton:Singleton = new Singleton(); } } }
Save and run it, you will see that it throws an error telling us to use the getInstance() function instead, so go ahead and do that:
package { import flash.display.MovieClip; public class Main exends MovieClip { public function Main() { var testSingleton:Singleton = Singleton.getInstance(); } } }
Save and run it, there’s no error now, and you can see in the console the text “Singleton instance created!”, meaning that it was created successfully.
So when you use a Singleton class, you cannot use new Singleton(), you have to use Singleton.getInstance() instead.
Step 7: Add Properties to the Class
The Singleton isn’t very useful at the minute. Let’s add a property:
package { public class Singleton { private static var instance:Singleton; //This will be the unique instance created by the class private static var isOkayToCreate:Boolean=false; //This variable will help us to determine whether the instance can be created //new example property: public var exampleProperty:String = "This is an example"; public function Singleton() { //If we can't create an instance, throw an error so no instance is created if(!isOkayToCreate) throw new Error(this + " is a Singleton. Access using getInstance()"); } //With this method we will create and access the instance of the method public static function getInstance():Singleton { //If there's no instance, create it if (!instance) { //Allow the creation of the instance, and after it is created, stop any more from being created isOkayToCreate = true; instance = new Singleton(); isOkayToCreate = false; trace("Singleton instance created!"); } return instance; } } }
Now, in Main.as, you can access testSingleton.exampleProperty just as if it were a normal class. Try tracing it out.
Step 7: Try Creating Another Singleton
To prove that the Singleton does what it’s supposed to do, create another singleton and change the example property of one of them:
package { import flash.display.MovieClip; public class Main exends MovieClip { public function Main() { var testSingleton:Singleton = Singleton.getInstance(); var anotherSingleton:Singleton = Singleton.getInstance(); anotherSingleton.exampleProperty = "This is set in anotherSingleton"; trace(testSingleton.exampleProperty, anotherSingleton.exampleProperty); } } }
What do you think will happen?
This even works if you create the Singleton variables in different classes.
Conclusion
The singleton pattern can be used on any code, and I highly recommend it if you are going to use just one instance of a class since it gives you better control of it. I hope you liked this Quick Tip, thanks for reading!
Saludos -Eduardo