JavaScript设计模式学习(四)单件(Singleton Pattern)

 

单件是JavaScript中最基本、最有用的设计模式,而你今后也会经常的使用这个模式。通过单件,我们可以把统一到一个逻辑单元中并且提供一个唯一的入口,这就保证你所有的引用都是用的这个全局资源。

 

单件的用途有:一、提供一个Namespacing、二、提供一种被称为branching的技术。

 

单件的基本形式:

 

/* Basic Singleton Pattern */

var
Map
=
{

    name:"Map G",

    createdate:"2008-09-19",

    

    sayMyName:function(){

        alert("My Name is "
+
this.name);

    },

    tellMeWords:function(arg){

        alert("What you told to me is "
+
arg
+
"\n I won't tell anyone!")

    }

}

 

命名空间:

 

我们可以给单件提供新的属性,并且能够创建独立的命名空间,而避免我们写的属性或者程序被无意的覆盖。我们接着单件的基本形式中的例子可以创建新的属性:

 

Map.Property
=
{

    createdata:"2000-09-09",

    width:"100",

    height:"200"

}

 

Map.Utility
=
{

    getSize:function(x,y){

        return
x*y;

    }

}

 

这样,同样的createdate属性即便一样,也不会造成程序中的冲突了。

 

在单件中添加私有成员:

 

利用下划线。最简单、最直接的声明私有变量的方式就是使用下划线。这样就可以使其他程序员明白,这些变量是私有的、只是在对象内部使用,同时也可以使其他程序员避免直接访问他们。

 

/* Basic Singleton Pattern */

var
Map
=
{

    name:"Map G",

    createdate:"2008-09-19",

    

    sayMyName:function(){

        alert("My Name is "
+
this.name);

    },

    tellMeWords:function(arg){

        alert("What you told to me is "
+
arg
+
"\n I won't tell anyone!")

    },

    _isMature:function(){

        alert("Of Course, I'm Mature!");

    }

}

 

使用Closure。

 

使用Closure,我们可以实现私有变量和共有变量。因为singleton在调用过程中只会有一个实例,所以我们就不必担心私有成员耗费资源的问题了。例子如下:

 

MyNamespace
=
{};

 

MyNamespace.Singleton
=
(function(){

    var
privateAttribute1
=
"Name";

    var
privateAttribute2
=
true;

    

    function
privateMethod1(){

        

    }

    

    return
{

        publicAttribute1:"Public",

        publicAttribute2:"false",

        publicMethod1:function(){

            

        }

    };

})();

 

Lazy Instantiation

以上所讨论的各种各样的单件实现,他们都有一个共同点,那就是当代码加载时就立即创建的。如果你有一个需要复杂配置的单件、或者他加载的时候需要占用大量资源,也许我们就该考虑延时实现他了。Lazy Loading就是用来解决这个问题的,常被用在需要加载大量数据的时候。

 

Lazy Loading singletons与之前的singleton不同,你不能通过MyNamespace.methdName()来进行访问,而必须通过Mynamespace.getInstance().methodName()来访问。GetInstance方法首先检查单件是否进行实例化,如果没有,则创建并返回,下面是例子:

 

//Lazy instantiation

Car
=
{};

Car.MyPorsche
=
(function(){

    var
uniqueInstance;

        

    function
CarOfPorsche(){

        var
name
=
"My Favorate Porsche";

        var
buydate
=
"2008-09-22";

        

        return
{

            speed:"120Kmp",

            getName:function(){

                return
name;

            }

        };

    }

    

    return
{

        getInstance:function(){

            if(!uniqueInstance){

                uniqueInstance
=
CarOfPorsche();

            }

            

            return
uniqueInstance;

        }

    };

})();

 

//Normal Singleton

Car.MyBenz
=
(function(){

    var
name
=
"My Benz Car";

    var
buydate
=
"2009-10-10";

    

    return
{

        speed:"140Kmp",

        getName:function(){

            return
name;

        }

    };

})();

 

Lazy loading的一个缺点是增加了代码的复杂性,而且代码开始变得难以理解。在调用的时候,我们需要通过Car.MyPorsche.getInstance().speed来调用,这就增加了代码的复杂行。当然,我们可以通过

            var
porsche
=
Car.MyPorsche.getInstance();

            alert(porsche.getName()
+
"'s speed is "
+
porsche.speed);

来简化调用。

 

分支(Branching):

 

分支是一项将不同浏览器的区别封装到动态方法中的技术。我们以创建XHR对象为例。对于大多数浏览器,XHR 是XMLHttpRequest对象的一个实例,或者是较早版本的IE的不同ActiveX的一个实例。这个方法总是伴随着对于浏览器的检测,如果我们没用用Branching这项技术,没次我们都需要运行浏览器检测的方法来检查,这降低了代码的效率。

 

一个更加高效的方式就是当代码加载时,根据浏览器的不同赋予一个固定的值,在不同的浏览器下,我们只执行这个实现的扩展。在运行时刻动态改变一个Function的内容,这正是JavaScript灵活的强大的所在。

 

那么分支如何应用在单件中呢,看下面的例子:

 

//Branching

//SimpleXhrFactory Singleton

var
SimpleXhrFactory
=
(function(){

    var
standard
=
{

        createObject:function(){

            return
new
XMLHttpRequest();

        }

    };

    

    var
activexNew
=
{

        createObject:function(){

            return
new
ActiveXObject("Msxml2.XMLHTTP");

        }

    };

    

    var
activexOld
=
{

        createObject:function(){

            return
new
ActiveXObject("Microsoft.XMLHTTP");

        }

    };

    

    var
testObject;

    try{

        testObject
=
standard.createObject();

        return
standard;

    }catch(e){

        try{

            testObject
=
activexNew.createObject();

            return
activexNew;

        }catch(e){

            try{

                testObject
=
activexOld.createObject();

                return
activexOld;

            }catch(e){

                throw
new
Error("No XMLHTTP Object found in this environment!");

            }

        }

    }

})();

 

什么时候使用单件:

 

当需要使用命名空间或者模块化你的代码的时候,应该尽量的使用单件。单件是JavaScript中使用最广泛的一个设计模式,无论在什么规模的项目中,你都能看到他的影子。

 

使用单件的好处:

 

单件的主要作用是提供了一个格式化你的代码的方法。通过吧相似的方法和属性集合到一个单间中,并且只能被实例化一次,你就可以更方便的调试代码。

时间: 2024-10-22 13:59:25

JavaScript设计模式学习(四)单件(Singleton Pattern)的相关文章

javascript设计模式交流(一) :Singleton Pattern

javascript|设计  即使是简单的脚本语言,应用良好的模式可以得到非常"优美"的代码和较高的效率.尤其是对于交互要求较高的B/S系统,非常有必要用设计模式来优化代码. 单件模式(Singleton Pattern)是一种非常基本和重要的创建型模式."单件"的职责是保证一个类有且只有一个实例,并提供一个访问它的全局访问点.在程序设计过程中,有很多情况下需要确保一个类只能有一个实例. 传统的编程语言中为了使一个类只有一个实例,最容易的方法是在类中嵌入静态变量,并

JavaScript设计模式学习之“类式继承”

 这篇文章主要介绍了JavaScript设计模式学习之"类式继承",本文直接用代码实例讲解类式继承的实现方法,需要的朋友可以参考下     在做一件事情之前,首先要清楚做这件事情的好处有什么,相信不会有哪个人愿意无缘无故的去做事情.一般说来,我们在设计类的时候,实际上就是希望能减少重复性的代码,使用继承可以完美的做到这一点,借助继承机制,你可以在现有类的基础上再次进行设计并且充分利用它们已经具备的各种方法,而对设计的修改也更为轻松.废话不多说了,举例说明: 代码如下: function

javascript设计模式:JavaScript设计模式学习一之接口

看完了<JavaScript王者归来>,在图书馆找了<JavaScript设计模式>来看,之前设计模式方面的书看过:<Head First 设计模式>.<设计模式之禅>,GOF的<Design Patterns: Elements of Reusable Object-Oriented Software>看了一部分.记得以前没这些基础的时候,看<JavaScript设计模式>简直是不知道作者在说什么.言归正传:准确的说,JavaScr

.Net设计模式实例之单例模式( Singleton Pattern)

一.单例模式简介(Brief Introduction) 单例模式(Singleton Pattern),保证一个类只有一个实例,并提供一个访问它的全局访问点.单例模式因为Singleton封装它的唯一实例,它就可以严格地控制客户怎样访问它以及何时访问它. 二.解决的问题(What To Solve) 当一个类只允许创建一个实例时,可以考虑使用单例模式. 三.单例模式分析(Analysis)1.单例模式结构 Singleton类,定义一个私有变量instance;私有构造方法Singleton(

java设计模式之单例模式(Singleton pattern)

单例模式的定义: Singleton pattern restricts the instantiation of a class and ensures that only one instance of the class exists in the java virtual machine. The singleton class must provide a global access point to get the instance of the class.        限制一个

《JavaScript设计模式》——9.4 Singleton(单例)模式

9.4 Singleton(单例)模式 Singleton(单例)模式被熟知的原因是因为它限制了类的实例化次数只能一次.从经典意义上来说,Singleton模式,在该实例不存在的情况下,可以通过一个方法创建一个类来实现创建类的新实例:如果实例已经存在,它会简单返回该对象的引用.Singleton不同于静态类(或对象),因为我们可以推迟它们的初始化,这通常是因为它们需要一些信息,而这些信息在初始化期间可能无法获得.对于没有察觉到之前的引用的代码,它们不会提供方便检索的方法.这是因为它既不是对象,也

设计模式学习笔记(九)—Singleton模式

<设计模式>一书对Singleton模式是这样描述的: 保证一个类只有一个实例,并提供一个访问它的全局访问点. 这个模式比较简单,下面给出一个例子: public class Singleton { private static Singleton instance; private Singleton(){ } public static Singleton getInstance(){ if(instance==null) instance=new Singleton(); return

JavaScript 设计模式学习 Singleton_js面向对象

复制代码 代码如下: /* Basic Singleton. */ var Singleton = { attribute1: true, attribute2: 10, method1: function() { }, method2: function(arg) { } }; 单件模式最主要的用途之一就是命名空间: /* GiantCorp namespace. */ var GiantCorp = {}; GiantCorp.Common = { // A singleton with c

Javascript设计模式学习(一)封装和信息隐藏

在我们编程的过程中,我们应该尽可能的把数据和函数处理信息隐藏在对象内部,在Javascript中,我们怎样来做呢? 虽然Javascript中没有其他面向对象语言的声明共有和私有的关键字,但是我们仍可以通过一些手段来达到这样的效果.我们可以这样理解封装和信息隐藏,信息隐藏是我们的目标,因为我们不想太多无关的信息暴露在对象之外,而封装就是实现我们目标的方法.封装就可以被定义为在对象内部隐藏数据表达和具体实现的细节. 下面来学习下怎么用Javascript来实现接口:   第一种是:Fully Ex