Flex Tip 1: Private Class Constructor and Singleton

January 17, 2008 – 12:27 pm

Currently, ActionScript doesn’t have support for private class constructors thus any class’s constructor can be accessed. But there are times when you’ll want your class to be instantiated just one time, meaning its constructor called just one time. This relates to the Singleton Pattern where a class is globally accessible in the application by a static function. We’ll get to the Singleton too but first lets see how we manage to have private class constructors.

See the code below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package tip1
{
    public class Tip1
    {
        public function Tip1()
        {
            PrivateClass.ping();
        }
    }
}

class PrivateClass
{
    public static function ping():void
    {
        trace( "PrivateClass::ping()" );
    }
}

First of all note that this code goes into a single .as file. What we have here is the main class Tip1 in package tip1 and another class PrivateClass outside the package. This class does all the trick, it is accessible from the main class in the package, but its not accessible from any other class (in other .as files). To test that it works, we called from Tip1 constructor a function from PrivateClass. First time you instantiate a Tip1 class in the application you should see PrivateClass::ping() text appear in the console. So first step is done, we got ourselves a “hidden” class. Now lets take the next step and make Tip1 class inaccessible by instantiation.

Change the constructor from the main class as following:

5
6
7
8
public function Tip1( privateClass:PrivateClass )
{
    PrivateClass.ping();
}

Now when you try to instantiate the class Tip1 you will get an error looking like this Error 1136: Incorrect number of arguments. Expected 1. If you try to add an argument of any type other than PrivateClass you get this Error 1118: Implicit coercion of a value with static type Object to a possibly unrelated type Tip1.as$210:PrivateClass and if you type blind new Tip1( new PrivateClass() ) you get this Error 1180: Call to a possibly undefined method PrivateClass. So there is no way you can create an instance of class Tip1. Its not a good method with these errors but its good that users get them at compile time, making them pay attention that Tip1 its a private-constructor class.

Lets move ahead and see how the Singleton gets in the picture. See the code below.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package tip1
{
    public class Tip1
    {
        private static var instance:Tip1;
       
        public static function getInstance():Tip1
        {
            if( instance == null )
            {
                instance = new Tip1( new SingletonEnforcer() );
            }
           
            return instance;
        }
       
        public function Tip1( enforcer:SingletonEnforcer ){}
    }
}

class SingletonEnforcer {}

What we added here is one static variable “instance” and one static function “getInstance”. The code is pretty straight forward, in getInstance method if there is no instance already created, create one and return it, if there is already one just return it. The PrivateClass earlier it’s now SingletonEnforcer and it’s listed as required parameter in Tip1 constructor. The class cant be instantiated from outside, the only usage is throw the static function Tip1.getInstance().[ method ] / [variable]. For example if you have the variable myVar in Tip1 you can access it by Tip1.getInstance().myVar.

The real value of the singleton class is that it is accessible from anywhere in the code, making it handy in situation where you dont want multiple instances to keep the same data, like in keeping the score in a game, or the total value of your shopping.

Post a Comment