单例模式
单例模式也称做为单子模式,更多的也叫作单体模式。为软件设计中较为简单可是最为经常使用的一种设计模式。
下面是维基百科对单例模式的介绍:
在应用单例模式时,生成单例的类必须保证只有一个实例的存在,不少时候整个系统只须要拥有一个全局对象,才有利于协调系统总体的行为。好比在整个系统的配置文件中,配置数据有一个单例对象进行统一读取和修改,其余对象须要配置数据的时候也统一经过该单例对象来获取配置数据,这样就能够简化复杂环境下的配置管理。
单例模式的思路是:一个类能返回一个对象的引用(而且永远是同一个)和一个得到该实例的方法(静态方法,一般使用 getInstance 名称)。那么当咱们调用这个方法时,若是类持有的引用不为空就返回该引用,否者就建立该类的实例,而且将实例引用赋值给该类保持的那个引用再返回。同时将该类的构造函数定义为私有方法,避免其余函数使用该构造函数来实例化对象,只经过该类的静态方法来获得该类的惟一实例。
对于 JS 来讲,巨大的灵活性使得其能够有多种方式实现单例模式,使用闭包方式来模拟私有数据,按照其思路可得:
- var single = (function(){
- var unique;
- function getInstance(){
- if( unique === undefined ){
- unique = new Construct();
- }
- return unique;
- }
- function Construct(){
- // ... 生成单例的构造函数的代码
- }
- return {
- getInstance : getInstance
- }
- })();
以上,unique即是返回对象的引用,而 getInstance即是静态方法得到实例。Construct 即是建立实例的构造函数。
能够经过 single.getInstance() 来获取到单例,而且每次调用均获取到同一个单例。这就是 单例模式 所实现的效果。
不过,对于JS来讲,显然以上循规蹈矩的方式显得过于笨重,在不一样的场景以不一样的方式实现单体模式正是 JS 的优点
实现1: 最简单的对象字面量
- var singleton = {
- attr : 1,
- method : function(){ return this.attr; }
- }
- var t1 = singleton ;
- var t2 = singleton ;
十分简单,而且很是使用,不足之处在于没有什么封装性,全部的属性方法都是暴露的。对于一些须要使用私有变量的状况就显得爱莫能助了。固然在对于 this 的问题上也是有必定弊端的。
实现2:构造函数内部判断
其实和最初的JS实现有点相似,不过是将对是否已经存在该类的实例的判断放入构造函数内部。
- function Construct(){
- // 确保只有单例
- if( Construct.unique !== undefined ){
- return Construct.unique;
- }
- // 其余代码
- this.name = "NYF";
- this.age="24";
- Construct.unique = this;
- }
- var t1 = new Construct() ;
- var t2 = new Construct() ;
那么也有的, t1 === t2 。
也是很是简单,无非就是提出一个属性来作判断,可是该方式也没有安全性,一旦我在外部修改了Construct的unique属性,那么单例模式也就被破坏了。
实现3 : 闭包方式
对于大着 灵活 牌子的JS来讲,任何问题都能找到 n 种答案,只不过让我本身去掂量孰优孰劣而已,下面就简单的举几个使用闭包实现单例模式的方法,无非也就是将建立了的单例缓存而已。
- var single = (function(){
- var unique;
- function Construct(){
- // ... 生成单例的构造函数的代码
- }
- unique = new Constuct();
- return unique;
- })();
只要 每次讲 var t1 = single; var t2 = single;便可。 与对象字面量方式相似。不过相对而言更安全一点,固然也不是绝对安全。
若是但愿会用调用 single() 方式来使用,那么也只须要将内部的 return 改成
return function(){
return unique;
}
以上方式也可使用 new 的方式来进行(形式主义的赶脚)。固然这边只是给了闭包的一种例子而已,也能够在 Construct 中判断单例是否存在 等等。 各类方式在各个不一样状况作好选着便可。
总结
总的来讲,单例模式相对而言是各大模式中较为简单的,可是单例模式也是较为经常使用而且颇有用的模式。在JS中尤其突出(每一个对象字面量均可以看作是一个单例么~)。
记住,是否严格的只须要一个实例对象的类(虽然JS没有类的概念),那么就要考虑使用单例模式。
使用数据缓存来存储该单例,用做判断单例是否已经生成,是单例模式主要的实现思路。