JavaScript 设计模式系列 : 单例(Singleton)模式

单例(SIngleton)模式:

  功能:   用来划分命名空间:

      1.减少网页中的全局变量的数量。

      2.可以在多人开发时避免代码命名冲突。

      3.一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。

在JavaScript里,单例作为一个命名空间提供者,从全局命名空间里提供一个唯一的访问点来访问该对象。单例模式就是用一个命名空间包含自己的所有代码的全局对象。在传统工程师眼中,单例就是保证一个类只有一个实例,实现的方法一般是先判断实例存在与否,如果存在直接返回,如果不存在就创建了再返回,这就确保了一个类只有一个实例对象。示例:

1.对象字面量方法

1 var functionFree = {
2     name:'free',
3     method:function(){
4           //code
5     },
6     init:function(){
7           //code
8     }
9 }

或者:使用实例化构造函数的方法

1 var functionFree = new  function myGroup(){
2      this.name = 'free',
3      this.getName = function(){
4      
5       }
6       ...
7 }

立即执行函数创建单体:

 1 var Singleton = function(){//这个匿名函数返回一个对象,将这个对象//赋值给Singleton
 2       return {};
 3 }();
 4 
 5 var Singleton = (function(){//这是声明之后立即调用
 6      return {};
 7 }());
 8 
 9 var Singleton = (function(){//这是声明之后立即调用
10      return {};
11 })();

 

2.扩展:如果要扩展对象,可以自定义私有成员和方法,然后使用闭包在内部封装这些变量和函数。暴露你想暴露的方法。

    闭包实现内部方法外部调用。这种模式又叫做模块模式(module pattern)。

 1 var mySingleton = function () {   
 2     /* 这里声明私有变量和方法 */    
 3        var privateVariable = 'something private';    
 4        function showPrivate() {        
 5             console.log(privateVariable);    
 6        }   
 7        /* 公有变量和方法(可以访问私有变量和方法) */    
 8        return {        
 9          publicMethod: function () {            
10             showPrivate();        
11           },        
12           publicVar: 'the public can see this!'    
13      };
14  };
15  var single = mySingleton();
16  single.publicMethod();  // 输出 'something private'
17  console.log(single.publicVar); // 输出 'the public can see this!'

3.用公有方法调用单例,在需要的时候才来初始化。将单例的代码放在init()函数中,第一次调用的时候才会实例化。

 1 var Singleton = (function () {
 2     var instantiated;
 3     function construct() {//将所有的单例代码放到这个construct函数中间来。这里不能从外部访问。我们需要一个公有的方法getInstance方法来返回这个方法。
 4         /*这里定义单例代码*/
 5         var param = "free";
 6         method1 = function(){
 7 
 8         }
 9         return {
10             publicMethod: function () {
11                 console.log('hello world');
12             },
13             publicProperty: 'test'
14         };
15     }
16 
17     return {
18         getInstance: function () {
19             if (!instantiated) {//判断类是否实例化
20                 instantiated = construct();//对象
21             }
22             return instantiated;
23         }
24     };
25 })();
26 
27 /*调用公有的方法来获取实例:*/
28 Singleton.getInstance().publicMethod();

 

其实单例一般是用在系统间各种模式的通信协调上,下面的代码是一个单例的最佳实践:

   外围是一个立即调用的函数,然后是一个构造函数,通过new生成一个单例instance,通过getInstance()传递进去参数,同时调用单例。

var SingletonTester = (function () {

//参数:传递给单例的一个参数集合
function Singleton(args) {

//设置args变量为接收的参数或者为空(如果没有提供的话)
var args = args || {};
this.name = 'SingletonTester';
this.pointX = args.pointX || 6; //从接收的参数里获取,或者设置为默认值
this.pointY = args.pointY || 10;

}

//实例容器
var instance;

var _static = {
name: 'SingletonTester',

//获取实例的方法
//返回Singleton的实例
getInstance: function (args) {
if (instance === undefined) {
instance = new Singleton(args);//实例化成对象调用
}
return instance;
}
};
return _static;
})();

var singletonTest = SingletonTester.getInstance({ pointX: 5 });
console.log(singletonTest.pointX); // 输出 5

 4>>分支:返回需要的对象,而不管具体含有多少对象。最终只实例化需要的对象。

 1 Singleton = (function(){
 2       var objectA = {
 3              method1:function(){...},
 4              method2:function(){...},
 5        };
 6       var objectB = {
 7              method1:function(){...},
 8              method2:function(){...},
 9        };
10        return (someCondition) ? objectA : objectB;
11 })();

 

 

 

posted on 2012-07-20 16:44  color_story  阅读(192)  评论(0编辑  收藏  举报

导航