JavaScript设计模式---单例模式详解【四种基本形式】

本文实例讲述了JavaScript设计模式---单例模式.分享给大家供大家参考,具体如下:

单例模式也称为单体模式,其中:

1,单体模式用于创建命名空间,将系列关联的属性和方法组织成一个逻辑单元,减少全局变量。
 逻辑单元中的代码通过单一的变量进行访问。

2,三个特点:
 ① 该类只有一个实例;
 ② 该类自行创建该实例,即在该类内部创建自身的实例对象;
 ③ 向整个系统公开这个实例接口

3,单体模式有四种基本形式:

第一种,最简单的单体,只被实例化一次    我简记为json对象

(1)基本结构

 var userInfo={//已经自行被实例化 其实是一json对象
    name:"测试名称",
    dept:"测试PD",
    code:"测试PD001",
    getName:function () {
      return "测试"
    }
  };

(2)使用方法与json的使用方法一致:使用点 " . "的方式访问

alert(userInfo.getName())

单体模式用来划分命名空间,并将一群相关的属性和方法组织到一起的简单介绍:

 var comm={};//一个空对象

  comm.userInfo={//空对象下的第一个命名空间
    name:"命名空间1下的",
    code:"001"
  }
  comm.funcInfo={//空对象下的第二个命名空间
    funcName:"命名空间2下的",
    code:"002"
  }

总结:该种方式可以看出对象的变量值不是动态加载的,而且对象没有显示初始化,由此有了第二种单体模式。

第二种,具有局部变量的单体

要求:模拟一个使用ajax从数据库加载数据的过程

(1)简单模拟一下ajax过程

//模拟一个Ajax操作
  function Ajax() {};//空对象
  //静态函数 模拟作为从数据库取值 此处值写死的
  Ajax.request=function (url,fn) {
    //默认永远回调成功
    if(true){
      fn("测试值1","测试值2")
    }
  }

(2)在最简单的单体中出现了数据不是动态从数据库加载的,而且没有显示实例化对象,此处使用闭包原理解决上述问题

//使用闭包的原理解决:动态从数据库加载数据 ,显示实例化
  var userInfo=(function () {
    //(1)利用闭包使单体有自己的私有局部变量
    var name="";
    var code="";
    //(2)利用ajax访问数据库取到数据
    Ajax.request("url",function (n,c) {//由于模拟的ajax中只是简单传递参数,所以第一个参数可以任意
         name=n;
         code=c;
    })
    //(3)单体实现私有变量的赋值
    return {
      name:name,
      code:code
    }
  })()

(3)使用该种方式的单体,不用实例化 可以直接返回一个单体 【因为使用userInfo时,直接return一个单体回来】

alert(userInfo.name);

总结:

(1)优点,灵活

(2)弊端:return 单体数据量比较大时,都需要从数据库取数据,每次加载都要执行,会影响程序性能。由于该种方式每次加载都要直接执行,return单体数据量大时会影响呈现的性能,于是有了第三种单体模式。

第三种,惰性单体 提供的解决方案为:调方法时才实例化单体,而不是加载时就执行。

于是在第二种的基础上进行修改为,

(1)模拟ajax从数据库加载数据不变

 //模拟一个Ajax操作
  function Ajax() {}
  //静态函数 模拟作为从数据库取值
  Ajax.request=function (url,fn) {
    //默认永远回调成功
    if(true){
      fn("测试值1","测试值2")
    }
  }

(2)动态从数据库加载数据 ,显示实例化,使用一个函数(Init())封装产生单体的函数,通过一个私有变量来返回函数(Init())

 //使用闭包的原理解决:动态从数据库加载数据 ,显示实例化
  var UserInfo=(function () {
    var userInfo="";//私有变量

    function Init() {//在产生单体方式为包裹一层初始化函数
      //利用闭包使单体有自己的私有局部变量
      var name="";
      var code="";
      //利用ajax访问数据库取到数据
      Ajax.request("url",function (n,c) {
        name=n;
        code=c;
      })
      //单体
      return {
        name:name,
        code:code,
      }
    }

    return {//此时开始调用初始化函数实现单体的产生
      getInstance:function () {
        if(userInfo){//userInfo=""为false
          return userInfo;
        }else {
          userInfo=Init();
          return userInfo;
        }
      }
    }

  })()

(3)使用   访问UserInfo对象里面的获取初始化获取对象的函数(getInstance())

  alert(UserInfo.getInstance().name);

总结:使用惰性单体实质上是通过对产生单体的函数进行再一次封装(使用函数封装),再在通过该类提供的唯一接口(getInstance()方法)访问初始化单体 的函数。

第四种,分支单体

简单的用处:做Ajax的时候根据不同的浏览器获得不同的XHR。(将浏览器之间的差异封装到动态方法,适用于解决浏览器之间的差异。)

比如下面一个简单的例子:在电脑不同分辨率的情况下初始化不一样的界面。(这里只是弹窗显示而已)

(1)获取电脑的分辨率

//得到机器的分辨率
  var screenWidth=window.screen.width;//width
  var screenHeight=window.screen.height;//height

(2)进行分支判断处理 ,将差异封装到动态方法中

 var portalInfo=(function () {    //单体
   var $1280_1024={info:'1,2,3,5'}//单体1
   var $1366_768={info:'4,2,1,2'}//单体2

     //动态图选择浏览器的差异结果(这里是分辨率)
     if(screenWidth==1280){
       return $1280_1024;//返回单体进行初始化
     }else if(screenWidth==1366){
       return $1366_768;//返回单体进行初始化
     }else {
       throw new Error("请检查你当前的电脑分辨率")
     }
   })();

(3)使用 ,获取最终的结果

alert(portalInfo.info)//我的结果为4,2,1,2 这是由于我的电脑的分辨率为1366*768

总结一下,对于分支单体有一个缺点:分支中,单体1和单体2都被创建了,并保存在内存中了,但只用到一个。需要在 计算时间 和 占用内存 两者中取舍。

感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.jb51.net/code/HtmlJsRun测试上述代码运行效果。

更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》

希望本文所述对大家JavaScript程序设计有所帮助。

(0)

相关推荐

  • JavaScript设计模式之单例模式详解

    最近项目不太忙,难得有时间看看书,平时挺喜欢js这门语言.也看过很多高级教程,觉得自己还是比较热衷于js的设计模式.这一次重温一下<JavaScript设计模式与开发实践>,开篇为单例模式. /** * pre 单例模式 * 定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点 * 应用:单例模式是一种常用的模式,有一些对象我们往往只需要一个, * 比如线程池.全局缓存.浏览器中的 window 对象等. */ //--------------singleton-01----------

  • 学习JavaScript设计模式(单例模式)

    单例模式的定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点. 单例模式是一种常用的模式,有一些对象我们往往只需要一个,比如线程池.全局缓存.浏览器的window对象.在js开发中,单例模式的用途同样非常广泛.试想一下,当我们单击登录按钮的时候,页面中会出现一个登录框,而这个浮窗是唯一的,无论单击多少次登录按钮,这个浮窗只会被创建一次.因此这个登录浮窗就适合用单例模式. 1.单例模式的使用场景 在使用一种模式之前,我们最好要知道,这种模式的使用场景.用了这么久的单例模式,竟全然不知!用它

  • JavaScript设计模式之观察者模式(发布者-订阅者模式)

    观察者模式( 又叫发布者-订阅者模式 )应该是最常用的模式之一. 在很多语言里都得到大量应用. 包括我们平时接触的dom事件. 也是js和dom之间实现的一种观察者模式. 复制代码 代码如下: div.onclick  =  function click (){ alert ( "click' ) } 只要订阅了div的click事件. 当点击div的时候, function click就会被触发. 那么到底什么是观察者模式呢. 先看看生活中的观察者模式. 好莱坞有句名言. "不要给我

  • JavaScript设计模式之单例模式实例

    <Practical Common Lisp>的作者 Peter Seibel 曾说,如果你需要一种模式,那一定是哪里出了问题.他所说的问题是指因为语言的天生缺陷,不得不去寻求和总结一种通用的解决方案. 不管是弱类型或强类型,静态或动态语言,命令式或说明式语言.每种语言都有天生的优缺点.一个牙买加运动员, 在短跑甚至拳击方面有一些优势,在练瑜伽上就欠缺一些. 术士和暗影牧师很容易成为一个出色的辅助,而一个背着梅肯满地图飞的敌法就会略显尴尬. 换到程序中, 静态语言里可能需要花很多功夫来实现装饰

  • JavaScript 设计模式 安全沙箱模式

    命名空间 JavaScript本身中没有提供命名空间机制,所以为了避免不同函数.对象以及变量名对全局空间的污染,通常的做法是为你的应用程序或者库创建一个唯一的全局对象,然后将所有方法与属性添加到这个对象上. 复制代码 代码如下: /* BEFORE: 5 globals */ // constructors function Parent() {} function Child() {} // a variable var some_var = 1; // some objects var mo

  • JavaScript实现设计模式中的单例模式的一些技巧总结

    一.使用全局变量保存单例 这是最简单的实现方法 function Person(){ this.createTime=new Date(); } var instance=new Person(); function getInstance(){ return instance; } 加载该js时就创建一个Person对象,保存到instance全局变量中,每次使用都取这个对象.如果一次都没使用,那么创建的这个对象则浪费了,我们可以优化一下, var instance function getI

  • 常用的Javascript设计模式小结

    <Practical Common Lisp>的作者 Peter Seibel 曾说,如果你需要一种模式,那一定是哪里出了问题.他所说的问题是指因为语言的天生缺陷,不得不去寻求和总结一种通用的解决方案. 不管是弱类型或强类型,静态或动态语言,命令式或说明式语言.每种语言都有天生的优缺点.一个牙买加运动员, 在短跑甚至拳击方面有一些优势,在练瑜伽上就欠缺一些. 术士和暗影牧师很容易成为一个出色的辅助,而一个背着梅肯满地图飞的敌法就会略显尴尬. 换到程序中, 静态语言里可能需要花很多功夫来实现装饰

  • js设计模式之单例模式原理与用法详解

    本文实例讲述了js设计模式之单例模式原理与用.分享给大家供大家参考,具体如下: 关于设计模式,我的理解是它是业务代码的提前解决方案.意思就是说在没有真正的业务之前,设计模式就存在了,这个是显然的.设计模式是人长期从事业务总结的具有普通适用性的解决方案. 就个人来讲,写了太多的命令式编程代码,所谓命令式代码就是业务需要怎样就写怎么样的功能,比如添加一个点击事件,比如进行一个验证等扥.写就写了很少站在设计模式的角度或者前人的角度去改善代码. 不给自己找客观原因,最近开始关注设计模式,尝试从设计模式的

  • javascript设计模式 – 单例模式原理与应用实例分析

    本文实例讲述了javascript设计模式 – 单例模式.分享给大家供大家参考,具体如下: 介绍:单例模式是结构最简单的设计模式.单例模式用于创建那些在软件系统中独一无二的对象,是一个简单但很实用的设计模式. 定义:确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法.单例模式是一种对象创建型模式. 场景:日常编码中会有很多需要重用的场景,例如弹窗,键盘输入这类公共组件,我们往往希望它只创建一次,在第二次使用时重复使用之前创建好的实例.为了节约

  • javascript设计模式之解释器模式详解

    神马是"解释器模式"? 先翻开<GOF>看看Definition:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子. 在开篇之前还是要科普几个概念: 抽象语法树: 解释器模式并未解释如何创建一个抽象语法树.它不涉及语法分析.抽象语法树可用一个表驱动的语法分析程序来完成,也可用手写的(通常为递归下降法)语法分析程序创建,或直接client提供. 解析器: 指的是把描述客户端调用要求的表达式,经过解析,形成一个抽象语法树的程序. 解

  • JavaScript 设计模式之组合模式解析

    怎么说呢?!就像是动物(组合对象)一样,当它生下后代(叶对象)时,它的后代就有了某种功能(比如:挖洞,听力好等等):也像是一棵树,它有一个根(组合对象)然后是从这个棵树向外冒出的其他枝杆(组合对象)以及从这些枝杆又向外长的叶子(叶对象).换句话说,就是当祖先已经有了,那么只要从这个祖先衍生出来的其他孩子(包括这个祖先下的其他组合对象)已经就具备了某种功能,看上去貌似又有些像是继承."组合模式"在组合对象的层次体系中有两种类型的对象:叶对象和组合对象.组合模式擅长于对大批对象进行操作.

  • JS 设计模式之:单例模式定义与实现方法浅析

    本文实例讲述了JS 设计模式之:单例模式定义与实现方法.分享给大家供大家参考,具体如下: 良好的设计模式可以显著提高代码的可读性,降低复杂度和维护成本.笔者打算通过几篇文章通俗地讲一讲常见的或者实用的设计模式. 今天先从最简单的一个入手:单例模式. 文中的示例代码会使用 ES6 语法,尽量简化不必要的细节 概念 单例模式(Singleton)属于创建型的设计模式,它限制我们只能创建单一对象或者某个类的单一实例. 通常情况下,使用该模式是为了控制整个应用程序的状态.在日常的开发中,我们遇到的单例模

随机推荐