Object Instantiation


To create a new instance of a class, you use the new keyword followed by the class name. This statement calls the constructor of the class and returns a new instance, as in this example:

var myObject:MyClass = new MyClass();


This approach is almost undoubtedly a concept with which you are already familiar, but if our class uses this type of instantiation, we have no way of controlling its creation. For us to control the instantiation, we're going to use a static method called getInstance(). Because it is static, it can be invoked before an instance of the class exists. The following is an example of a class that uses this method:

public class MyClass {    public function MyClass() {}    public static function getInstance():MyClass {       return new MyClass();    } }


Now we can create our instances of the class by using the static method, like this:

var myObject:MyClass = MyClass.getInstance();


Restricting Instantiation

As long as the instance is always accessed via the static getInstance() method, everything works according to plan. However, notice that there is nothing to prevent someone from constructing a second instance using the new keyword. In other languages this problem would be solved by making the constructor private, but private constructors aren't supported in ActionScript 3.0.

We could just leave the constructor public and put a big comment up at the top of the class telling other developers that this class should be instantiated only once. However, one of our goals in object-oriented programming should be to create a class that cannot be broken by improper implementation. We'll talk more about convention, as opposed to rules, later in this chapter.

So, we have a few other options at our disposal that allow us to limit instantiation. One feature of ActionScript 3.0 is that all parameters of a method are now required unless a default value is provided. This feature includes the constructor. Therefore, you can add a parameter to the constructor that is required and type it to something that is available only from inside the class.

Note

This is not an absolute restriction since someone can get around this by passing null into the constructor. However, it is the best we can do without a true private constructor.


A second new feature of ActionScript 3.0 is the ability to add multiple class definitions to one file. You can access only one of the classes from outside the ActionScript file, and that is the classinside the package definitionwith the same name as the file name. But you can put other classes outside the package in the same file, and those classes are available only to the primary class. We'll use this feature to create a "private" class and make it our constructor parameter's type. It's actually easier than it sounds:

package {    public class MyClass {       public function MyClass(enforcer:SingletonEnforcer) {}       public static function getInstance():MyClass {          return new MyClass(new SingletonEnforcer());       }    } } class SingletonEnforcer {}


You can now create an instance of MyClass using the following code:

var myInstance:MyClass = MyClass.getInstance();


Note that our current implementation doesn't yet enforce a single instance of the class. Each time we call getInstance() our class will return a new instance. In the next section we'll look at how to ensure that there's only ever one instance.

Single Instance and Global Access

What can we do to enforce that the class is instantiated only once? Right now, the getInstance() method can be called multiple times just like a normal public constructor; and we also need to provide global access to this one instance. By modifying the getInstance() method slightly and adding a static property to hold our single instance, we'll knock out both of these requirements at once.

First let's add a private static property to the class that will hold our single instance. We need to make the property static so that it is available to our getInstance() method. Now when the static getInstance() method is called it creates an instance and stores it in the private static _instance property before returning the newly created instance. Here is how our class looks now:

package {    public class MyClass {       private static var _instance:MyClass;       public function MyClass(enforcer:SingletonEnforcer) {}       public static function getInstance():MyClass {          MyClass._instance = new MyClass(new SingletonEnforcer());          return MyClass._instance;       }    } } class SingletonEnforcer {}


Next, we're going to modify the getInstance() method so that it checks whether this single instance has already been created. If it has, then it returns that instance without calling the constructor again. Check out this modification:

package {    public class MyClass {       private static var _instance:MyClass;       public function MyClass(enforcer:SingletonEnforcer) {}       public static function getInstance():MyClass {          if(MyClass._instance == null) {             MyClass._instance = new MyClass(new SingletonEnforcer());          }          return MyClass._instance;       }    } } class SingletonEnforcer {}


convention versus rules

If you're new to design patterns, at first glance the Singleton pattern seems a bit like over engineering. You might be saying to yourself, "If I want only one instance of a class, then I'll create only one instance; if I need global access, then I'll stick it in some global variable." Although you could certainly do those two thingsand they would probably workthey 'could pose problems in a team development environment. 'You may also have trouble with this approach if you're creating multiple versions of the application.

This underscores the importance of following structural rules rather than simple conventions. The idea of encapsulation in object-oriented programming is that a class should be self-contained. It should have well-documented inputs in the form of public methods and setters and outputs in the form of events. These inputs and outputs are commonly known as the API (Application Programming Interface). As we mentioned earlier, classes should function like a black box: nothing exposed in the API should permit improper implementation to "break it." In the case of our Singleton class, we should not allow another object to create more than one instance of the class. (See Chapter 1, "Designing Applications.")





Advanced ActionScript 3 with Design Patterns
Advanced ActionScript 3 with Design Patterns
ISBN: 0321426568
EAN: 2147483647
Year: 2004
Pages: 132

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net