技术开发 频道

软件设计模式在JavaScript中的应用

  但遗憾的是,以上的代码不能禁止用户直接实例化Singleton类。例如,通过以下语句实例化Singleton类仍然是成立的:

var instA =new Singleton ();


  而随后你调用如下语句也是成立的:

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

  因此,我们需要进一步修改Singleton类的构造函数,使得Singleton类只能在Singleton.getInstance方法中进行实例化。

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

  这样当用户试图自己创建多个对象的时候,通过人工抛出异常来阻止。不过这么做你感觉是不是还是有一点别扭?创建单例就创建单例吧,干嘛非要抛出一个异常呢?但无论如何,使用上述方案已经能够实现了仅能创建类的单例的目的。

  下面,我们来讨论第三种方法(也是最优秀的方法)。这种方法巧妙利用了JavaScript对于“匿名”函数的支持特征来间接实现禁止对Singleton类构造函数的访问,从而较好地模拟了私有构造函数的特性,最终比较完美地解决了用JavaScript实现Singleton模式的问题。

  列表2:借助于“匿名”函数的支持在JavaScript中创建Singleton模式类

<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(
"试图通过new SingletonObject()构造实例!");
    instA
= new SingletonObject();
}
catch(e){
    alert(
"SingletonObject构造函数不能从外部访问,系统抛出了异常!");
}
instA
= SingletonFactory.getInstance();  //通过Factory上定义的静态方法获得
var instB = SingletonFactory.getInstance();
instA.methodA();
instB.methodA();
alert(instA
== instB); //成功    
</script>

  上面的第三种创建方式可谓挖空心思,穷JavaScript之能事,但终于获取了令人满意的效果。

0
相关文章