JavaScript 设计模式之----单体,单例模式


1、介绍

从本章开始,我们会逐步介绍在JavaScript里使用的各种设计模式实现,在这里我不会过多地介绍模式本身的理论,而只会关注实现。OK,正式开始。

在传统开发工程师眼里,单例就是保证一个类只有一个实例,实现的方法一般是先判断实例存在与否,如果存在直接返回,如果不存在就创建了再返回,这就确保了一个类只有一个实例对象。在JavaScript里,单例作为一个命名空间提供者,从全局命名空间里提供一个唯一的访问点来访问该对象。


2、 简单单体与闭包单体

在JavaScript里,实现单例的方式有很多种,其中最简单的一个方式是使用对象字面量的方法,其字面量里可以包含大量的属性和方法:

<!DOCTYPE html>
<html>
<head>
    <meta name="name" content="content" charset="utf-8">
    <title>javascript单体模式</title>
</head>
<body>
    <script>
    //单体模式(sigleton)--无法new();因为他已经真是存在了

    /*1、简单单体--对象自变量的模式*/
/*  var Sigleton ={
       attr1 : true,
       attr2 : 10,
       method1: function(){
       alert("我是方法1");
},
method2 : function(){
    alert("我是方法2");
}
    };
    alert(Sigleton.attr1);

    //单体模式主要是划分命名空间,区分不同人之间的代码
    var BHX =BHX || {};
    BHX.Sigleton ={
        attr1 : true,
attr2 : 10,
method1: function(){
alert("我是方法1");
},
method2 : function(){
    alert("我是方法2");
}
    };
    BHX.Sigleton.method1();*/


    /*2、闭包单体---借用闭包穿简单体(闭包的主要目的:保护数据)*/
    //命名空间--块级作用域的实现

 /*     (function test(){
            alert(11);
        })()*/

    var BHX = BHX || {};
    BHX.Sigleton2=(function(){
    //用闭包的作用就是把自己的私有属性给封装起来,不让外界访问。只有return暴露出来才能访问。
        var a1 = true;
        var a2 = 10;
        var f1 = function(){
            alert("function f1");
        };
        var f2 = function(){
            alert("function f2");
        };

        //要把块级作用域的东西赋值给Sigleton2,要有return语句。
        return{
            attr1 : true,
    attr2 : 10,
    method1: function(){
    return f1();
    },
    method2 : function(){
        return f2;
    }

    };

    })();

    alert(BHX.Sigleton2.attr1);
    BHX.Sigleton2.method1();

    </script>
</body>
</html>

上面的代码很不错了,但如果我们想做到只有在使用的时候才初始化,那该如何做呢?为了节约资源的目的,我们可以另外一个构造函数里来初始化这些代码,如下:

3、 惰性单体和分支单体

<!DOCTYPE html>
<html>
<head>
    <title>javascript 单体模式2</title>
</head>
<body>
<script>
    /*3、惰性单体---(和闭包单体有一些相似的地方)但是可以用变量来控制要返回那些内容,而不是所有的都返回,这样在大项目中很有好处*/
    //命名空间
    var BHX = BHX || {};
    BHX.Base =(function(){

        //利用私有变量控制 返回的单体对象
        var uniqueInstance; //undefined

        //需要一个构造器init 初试化对象的方法
        function init(){
            var a1 = true;
            var a2 = 10;
            var f1 = function(){
                alert("function f1");
            };
            var f2 = function(){
                alert("function f2");
            };

            return{
                attr1 : true,
                attr2 : 10,
                method1: function(){
                    return f1();
                },
                method2 : function(){
                    return f2;
                }

            };
        };


        return {
            getInstance:function(){
                if (!uniqueInstance) { //如果不存在,则创建单体实例
                    uniqueInstance =init();
                };
                return uniqueInstance;
            }

        };
    })();

    //BHX.Base.getInstance().method1();

    /*4、分支单体--和swich  if else类似,可以用于底层框架浏览器的差异性检测*/

    var Ext =Ext ||{};
    var diff = true;

    Ext.More =(function(){
        var ObjA={          //火狐浏览器
            //属性1
            attr1:"火狐属性1"
            //属性2
            //方法1
            //方法2
        };
        var ObjB={
            //属性1
            attr1:"IE属性1"
            //属性2
            //方法1
            //方法2
        };
        return (diff)? ObjA : ObjB;
    })();
    alert(Ext.More.attr1);

</script>
</body>
</html>

知道了单例如何实现了,但单例用在什么样的场景比较好呢?其实单例一般是用在系统间各种模式的通信协调上,下面的代码是一个单例的最佳实践:

4、 最佳实践

var SingletonTester = (function () {

    //参数:传递给单例的一个参数集合
    function Singleton(args) {

        //设置args变量为接收的参数或者为空(如果没有提供的话)
        var args = args || {};
        //设置name参数
        this.name = 'SingletonTester';
        //设置pointX的值
        this.pointX = args.pointX || 6; //从接收的参数里获取,或者设置为默认值
        //设置pointY的值
        this.pointY = args.pointY || 10;

    }

    //实例容器
    var instance;

    var _static = {
        name: 'SingletonTester',

        //获取实例的方法
        //返回Singleton的实例
        getInstance: function (args) {
            if (instance === undefined) {
                instance = new Singleton(args);
            }
            return instance;
        }
    };
    return _static;
})();

var singletonTest = SingletonTester.getInstance({ pointX: 5 });
console.log(singletonTest.pointX); // 输出 5 

5、其他实现方式

参考可见博客:(http://www.cnblogs.com/TomXu/archive/2012/02/20/2352817.html)

版权声明:本文为小平果原创文章,转载请注明:http://blog.csdn.net/i10630226