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模式,能够对代码进行组织,把相关的方法和属性组织在一个不被实例化多次的单体中,以方便我们以后的维护。这就是单体模式的优点。
假设还想对单体模式有很多其它了解的话,请详见一下博客。