zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    python爬取代理IP地址
    神经网络训练的过程
    机器学习中用到的数学概念
    Navicat连接Mysql错误代码1251
    mysql安装
    mysql运行找不到MSVCP140.dll
    tomcat 日志乱码
    扁平化 Flat
    常见的WEB安全及防护
    CentOS ceph 集群搭建(单节点)
  • 原文地址:https://www.cnblogs.com/dingxiaoyue/p/4948241.html
Copyright © 2011-2022 走看看