美文网首页前端进阶与开发实践
翻滚吧,设计模式之01单例模式笔记

翻滚吧,设计模式之01单例模式笔记

作者: 莫闻 | 来源:发表于2017-05-10 23:06 被阅读14次

    设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理地运用设计模式可以完美地解决很多问题,每种模式在现实中都有相应的原理来与之对应,每种模式都描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是设计模式能被广泛应用的原因。-- 摘自网络

    总之一句话,想提高自己的coding能力,设计模式是非常非常重要的,尤其是在大型项目中。

    单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例。即一个类只有一个对象实例。

    • 要是以前没有接触过相关概念的童鞋,可能现在一脸懵逼。不过没关系,现在就让我们从最简单的一个例子说起。

      基础版

    
    //先看下这个简单的一个单例,getSingle函数会返回一个函数,无论这个函数执行多少次都只是创建一个相同的对象。
    
    var getSingle = function(fn){
    
        var _ret;
    
        return function(){
    
          //如果生成过,就不再生成。直接返回上一次生成的
    
          return _ret || (_ret = fn.apply(null,arguments));//传入的匿名函数直接执行,如下面的代码。返回一个对象{name:name},这里的arguments指的就是传入的参数name
    
        }
    
    };
    
    var getScript = getSingle(function(name){
    
        return {name:name}
    
    });
    
    var s1 = getScript(1);//只会生成这一次的
    
    var s2 = getScript(2);
    
    console.log(s1 == s2);//true
    
    

    进阶版

    
    //如同上栗所说,核心思想就是:如果生成过,就不再生成。直接返回上一次生成的对象
    
    var Single = function(name) {
    
      this.name = name;
    
    }
    
    Single.prototype.getName = function() {
    
      console.log(this.name);
    
    }
    
    Single.getInstance = function(name) {
    
    //看这里
    
      if(!this.instance){
    
        this.instance = new Single(name);
    
      }
    
      return this.instance;
    
    }
    
    var s1 = Single.getInstance('jack');
    
    var s2 = Single.getInstance('rose');
    
    console.log(s1 === s2);// true
    
    
    • 看到这里你可能就说了,这个有卵用啊,我要怎么用啊,好了下面我们就来搞一个例子来看看效果。

    举个栗子:

    • 现在我们要使用单例模式来创建一个页面中唯一的一个div
    
    var createDiv = (function() {
    
      var instance = null;
    
      var createDiv = function(html){
        if(instance){
          return instance;
        }
    
         this.html = html;
    
        this.init();
    
        return instance = this;
    
      }
    
      createDiv.prototype.init = function(){ 
    
        var div = document.createElement( 'div' );
    
         div.innerHTML = this.html; 
    
        document.body.appendChild( div );
    
      };
    
      return createDiv;
    })();
    var c1 = new createDiv("1");
    
    var c2 = new createDiv("2");
    
    console.log(c1===c2);//true
    
    //好了,现在我们就页面创建了一个<div>1</div>,我们来简单分析下,首先我们要熟悉原型和this等相关重要知识点,这里就不展开说明了,创建一个单例div,这里使用构造函数createDiv
    
    //此处使用了一个沙箱将函数包裹起来,返回了一个新的createDiv函数,
    
    //在原型链上定义了一个init方法,用来创建div,在构造函数中,首先判断是否创建过实例,有的话就直接返回,没有的话,调用init方法创建一个,最后返回instance.简单来说就是,构造函数负责:1.创建对象就是那个初始化init,2.保证只有一个对象
    
    

    改进版

    • 为了把instance封装起来,我们使用了自执行的匿名函数和闭包,并且让这个匿名函数返回

    真正的Single构造方法,这增加了一些程序的复杂度,阅读起来也不是很舒服。

    所以我们可以进行改进

    
    var index = 0;
    
    var bindOnce = getSingle(function(){
    
    index++;
    
    document.getElementById('btn').addEventListener("click",function(){
    
    alert(index);
    
    });
    
    return true;
    
    });
    
    var render = function(){
    
    console.log('开始渲染了');
    
    bindOnce();
    
    }
    
    render();
    
    render();
    
    render();
    
    可以看到,render函数和bindEvent函数都分别执行了3次,但div实际上只被绑定了一个
    
    事件。
    
    

    参考自javascript设计模式与开发实践

    相关文章

      网友评论

        本文标题:翻滚吧,设计模式之01单例模式笔记

        本文链接:https://www.haomeiwen.com/subject/kodntxtx.html