1.单利模式简介
在《设计模式》中单利模式是一种比较简单的模式,定义如下:
确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
在javascript中则将代码组织为一个单元,这个逻辑单元可以通过一个单一的变量访问,确保这个对象只存在一份实例。
单体类在javascript中可以用来划分命名空间、减少网页中全局变量的数目。
小结:其实就是把所有的代码封装到一个类中,访问时就通过这个类访问。好比生活中常见的电视遥控。把所需要的操作都封装到遥控上,访问电视时,直接通过遥控操作即可。
2.基本结构
我们平时用到的对象字面量就是所谓的单利模式,因为它把一批相关的属性和方法组织到了一起。
<span style="font-family:SimSun;font-size:18px;"> //通过对象字面量的形式来为对象创建属性和方法 var Singleton = { attribute1: true, attribute2: 10, //方法一 method1: function () { }, //方法二 method2: function (arg) { } }; //修改对象属性 Singleton.attribute1 = false; var total = Singleton.attribute2 + 5; //读取对象方法 var result = Singleton.method1();</span>
在上述代码中,所有的变量和方法必须通过Singleton对象来访问,你也可以扩充这个对象。当然这也违背了《设计模式》中的开闭原则,如果真要包含一些私有变量的话,可以采用函数嵌套,也就是闭包的操作。
3.划分命名空间
正如单体对象的定义所示:所有单体对象的内部成员都被包装在这个单体对象中,并且这些成员只能通过这些单体对象变量来进行访问。所以我们平常所用的命名空间就可以达到这个效果。
<span style="font-family:SimSun;font-size:18px;"> //定义一个全局对象 //定义一个公司的全局对象 var Business = { }; //然后可以分门别类地把自己的代码组织到这个全局对象的各个对象单体中 //公司的管理部 Business.Adminstration = { //方法一 method1: function () { } }; //公司的运作部 Business.Operation = { //方法二 method2: function () { } }; //公司的广告部 Business.advertisement = { //方法三 method3: function () { } }; Business.Adminstration.method(); //正确调用 var a = new Business(); //not a constructor a.Adminstration.method(); //error</span>
通过把处理不同的代码分门别类的做一下规划处理,放到不同的命名空间中,这样就会减少程序的错误。正如上述代码所示,首先建立一个公司的全局对象,然后分门别类的把各个部分划分开,职责划分清晰,减少了对象间的联系,减少了出错的可能性。
4.使用闭包
在前面的博客中曾经提到有关闭包的概念。在闭包中,把变量和函数定义在构造函数内使他们成为私用成员,并且还定义了一个类似于特权的函数,用来达到外部可以访问这些私有成员的目的,但是我们知道使用闭包实例化类的时候,所有生命在构造函数内的方法和属性都会再次创建一份,这也是闭包的不利处所在。
因为单体只会被实例化一次,所以你不必担心自己在构造函数内声明了多少方法和属性,因为所有的方法和属性都只会被实例化一次。
<span style="font-family:SimSun;font-size:18px;"> <script> MyNamespace.Singleton = (function() { // 私有成员 var privateAttribute1 = false; var privateAttribute2 = [1, 2, 3]; function privateMethod1() { } function privateMethod2(args) { } //闭包 return { publicAttribute1: true, publicAttribute2: 10, publicMethod1: function() { }, publicMethod2: function(args) { } }; })(); </script></span>
通过单体加闭包的操作就可以访问到对象内部的私有变量了。
5.延迟实例化
由于单体对象都是在脚本加载的时候被创建出来的,如果我们在加载的时候,并不需要单体,那么我们又该如何操作来推迟单体对象的加载呢?
其实我们只要在其中加入一个静态的方法,用来声明什么时候调用即可。
<span style="font-family:SimSun;font-size:18px;"> <script> /* 单体对象 */ MyNamespace.Singleton = (function() { var uniqueInstance; // Private attribute that holds the single instance. function constructor() { // 具体的代码细节 } return { /*用来实现延迟加载*/ getInstance: function() { if(!uniqueInstance) { // 判断仅且只有一个单体对象 uniqueInstance = constructor(); } return uniqueInstance; } } })(); </script></span>
其实与上述相比,主要的操作就是多了一个静态的方法,用来实现判断和延迟加载。
6.小结
本篇博客主要讲解了单体模式在javascript中的应用,通过运用javascript模式,可以对代码进行组织,把相关的方法和属性组织在一个不被实例化多次的单体中,以方便我们以后的维护。这就是单体模式的好处。
如果还想对单体模式有更多了解的话,请详见一下博客。
原文:http://blog.csdn.net/luckyzhoustar/article/details/38800127