Working with GoF's Design Patterns in JavaScript Programming
page 2 of 8
by Xianzhong Zhu
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 79846/ 119

Working with the Singleton Pattern

First of all, let us look at how the simplest yet commonly-used pattern, the Singleton pattern, is achieved in JavaScript.

(1) Concept

As a very fundamental and important pattern, the Singleton pattern is used to guarantee that there is one and only one instance for a given class, and provide an overall point to visit it.

Under a lot of practical circumstances, you usually need to insure there is one and only one instance related to a specified class. For this, traditional languages often resort to embedding a static variable in the class definition, setting up this variable in the first instance and making corresponding verifications whenever using the constructor of the instance. That is to say, no matter how many instantiations you have established, the static variable only relates to one instance. To prevent from instantiating a class more than one time, you need to declare the constructor function as private type, so that you can only establish the instance in the static method.

In the JavaScript language, although we still can specify a static method to construct an object, because we cannot make use of the "private" characteristic of the constructor function to forbid creating more than one instances, it is not as simple as that imagined to completely carry out the Singleton pattern.

(2) Example

Assume that we want to create an object which serves as a tool helper, including no business logic and any data required to be changed. Obviously, when you use such an object you do not need to instantiate the class each time -- one and only instance is enough for global invocation.

According to the analysis above, we can use JavaScript code (Listing 1) to carry out the Singleton pattern. This can insure there is one and only one instance relating to a given class, and provide an overall site to access it.

Listing 1: Establish the Singleton pattern in the JavaScript

function Singleton(){
 this.property1=”hello”;
 this.methodl=function(x,y){
 return x+y;
}
//define a static property
Singleton._instance_=null;
Singleton.getInstance=function(){
  if(this._instance_==null){
   //if there is no instance for class Singleton, 
 then create one
   this._instance_=new Singleton();
  }
  //return the instance of class Singleton
  return this._instance_;
};

The getInstance method first judges whether the static property Singleton._instance_ is null. If so, then it sets up an instance of the Singleton object and stores it in property Singleton._instance_. Finally, the Singleton._instance_ property is returned.

As for the usage of the Singleton class, it is easy:

Listing 2

//return only one instance
var instA =Singleton.getInstance();

Regrettably, the above code cannot prevent a user from instantiating the Singleton class directly. For example, it is still OK to set up an instance of the Singleton class through the following sentence.

Listing 3

var instA =new Singleton ();

And later on, it is also valid to make the following invocations.

Listing 4

alert(typeof(instA));
alert(instA.property1);

Therefore, we need a further modification with the definition of the Singleton structure so that you can only instantiate the Singleton class in the Singleton.getInstance method. Please look at the following solution.

Listing 5

function Singleton(){
if(Singleton.caller!=Singleton.getInstance){
throw new Error(”Can not new 
 Singleton instance!”);
}
…… (omitted)
}

Now, whenever the user tries to establish several instances, an exception is thrown out. However, it still feels some awkward, doesn't it? But anyway, we have already used the above-mentioned solution to achieve our initial purpose-- creating one and only instance of a given class.

Next, we start to discuss the third method (also a second to none method). This kind of method skillfully makes use of JavaScript's support toward "anonymous" function to indirectly achieve the target of forbidding the access to the constructor function of class Singleton, which preferably imitates the characteristic of private constructor function and perfectly solves the problem that JavaScript carries out the Singleton pattern. Listing 6 below shows this kind of best solution.

Listing 6: with the help of "anonymous" function to implement the Singleton pattern in JavaScript

<script type="text/javascript">
(function(){
    //SingletonFactory Interface
    SingletonFactory = {
        getInstance : getInstance
    }
 
    //private classes
    function SingletonObject()
    {
        SingletonObject.prototype.methodA = 
          function()
        {
            alert('methodA');
        }
        SingletonObject.prototype.methodB = 
       function()
        {
            alert('methodB');
        }
        SingletonObject.instance = this;
    }
   
    //SingletonFactory implementions
    function getInstance()
    {
        if(SingletonObject.instance == null)
            return new SingletonObject();
           
        else
            return SingletonObject.instance;
    }
})();
 
var instA = null;
try
{
    alert("Try to create an instance using new SingletonObject()!");
    instA = new SingletonObject();
}
catch(e){
    alert("You cannot access the constructor of SingletonObject externally!");
}
//create the target instance with the help of the 
 // static method from the Factory
 instA = SingletonFactory.getInstance();
var instB = SingletonFactory.getInstance();
instA.methodA();
instB.methodA();
alert(instA == instB); //OK
</script>

Ha, the third solution finally finds out a way to it by digging into the ability of "poor" JavaScript, but finally obtains decent effect.


View Entire Article

User Comments

No comments posted yet.

Product Spotlight
Product Spotlight 





Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-04-24 2:40:51 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search