单例模式

1、单例模式

单例模式,顾名思义为它限制一个类只能有一个实例化对象。

var mySingleton = (function () {
  // 实例存储了对单例对象的引用
  var instance;
  function init() {
    // 单例 
    // 私有方法和变量 
    function privateMethod(){
        console.log( "I am private" );
    }
    var privateVariable = "Im also private";
    var privateRandomNumber = Math.random();
    return {
      // 共有方法和变量 
      publicMethod: function () {
        console.log( "The public can see me!" );
      },
      publicProperty: "I am also public",
      getRandomNumber: function() {
        return privateRandomNumber;
      }
    };
  };
  return {
    // 如果存在获取此单例实例,如果不存在创建一个单例实例 
    getInstance: function () {
      if ( !instance ) {
        instance = init();
      }
      return instance;
    }
  };
})();
var myBadSingleton = (function () {
  // 存储单例实例的引用 
  var instance;
  function init() {
    // 单例 
    var privateRandomNumber = Math.random();
    return {
      getRandomNumber: function() {
        return privateRandomNumber;
      }
    };
  };
  return {
    // 总是创建一个新的实例 
    getInstance: function () {
      instance = init();
      return instance;
    }
  };
})();
// 使用: 
var singleA = mySingleton.getInstance();
var singleB = mySingleton.getInstance();
var badSingleA = myBadSingleton.getInstance();
var badSingleB = myBadSingleton.getInstance(); 

那么:

singleA.getRandomNumber() === singleB.getRandomNumber() 一定成立;

badSingleA.getRandomNumber() === badSingleB.getRandomNumber()几乎不成立。

原因:

  在badSingleA与 badSingleB实例化中,不论是否存在这样的实例,都重新创建实例,那么得到的随机数也不会相同。                

  在var singleA = mySingleton.getInstance()时,已经存储了对单例对象的引用的这样一个实例,那么再对singleB实例化时,这样的实例已经存在,不需要再创建新的实例,那么两个实例其实是一样的。

  而这就是我们所说的单例模式,它允许一个类只能有一个实例化对象。

2、单例模式应用描述

i.   每个类只有一个实例,这个实例必须通过一个广为人知的接口,来被客户访问。

ii.  子类如果要扩展这个唯一的实例,客户可以不用修改代码就能使用这个扩展后的实例,比如:

mySingleton.getInstance = function(){
  if ( this._instance == null ) {
    if ( isFoo() ) {
       this._instance = new FooSingleton();
    } else {
       this._instance = new BasicSingleton();
    }
  }
  return this._instance;
};

不需要去更新每个访问单例的代码。FooSingleton可以是BasicSinglton的子类,并且实现了相同的接口。

3、高度抽象的单例模式 -- 惰性单例

惰性单例,意图解决:需要时才创建类实例对象。惰性单例也是解决 “按需加载” 的问题。

例如点击产生页面弹窗,多次点击都只有这一弹窗对象,内容不同而已。

//单例模式抽象,分离创建对象的函数和判断对象是否已经创建
var getSingle = function (fn) {
    var result;
    return function () {
        return result || ( result = fn.apply(this, arguments) );
    }
};

4、单例模式优缺点

优点:适用于单一对象,只生成一个对象实例,避免频繁创建和销毁实例,减少内存占用。

缺点:不适用动态扩展对象,或需创建多个相似对象的场景。

12-25 01:41
查看更多