首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >大话设计模式(一)- 单例模式

大话设计模式(一)- 单例模式

作者头像
zhaozhen
发布2021-07-15 10:46:52
3870
发布2021-07-15 10:46:52
举报

大话设计模式(一)- 单例模式

单例模式在前端中很常见, 一个Vue实例,一个JQuery实例,都可以叫做单例模式。单例模式的主要作用一般用来创建命名空间,隔离模块,创建一个小型的代码库时使用,防止代码污染。

命名空间

命名空间:将代码都隔离在一个对象中,通过对象的方法调用,来进行操作。

var $ = {
 g: function() {
   return document.getElementById(id)
  }
  css: function(id ,key, value) {
   g(id).style[key] = value
  }
}

上面这段代码通过一个对象的来承载查询元素的方法,达到命名空间的目的.

模块化

单例模式在常用的代码库中用作模块化。

let moduleName = {
 dom:{

 }, // dom操作类
 event:{
 
 }, // 事件类
  string:{

  } // 字符串处理
}

当我们需要对相应的方法做拓展时可以直接添加各应用的方法就可以在某一些方法下直接增加拓展的方法。

创建小型代码库

此时我们尝试用现在学到的方法来规范我们的代码库。

 var moduleName = {
 utils:{
 
 },
 Tool:{
 },
 ajax:{
 },
 others:{

  }
}
// 此时在调用方法时 即可用moduleName.utils.method() 来调用方法。

静态变量存储器

在ES6 以前由于不存在静态变量,通常,我们使用闭包解决静态变量的问题。

var constConfig= (function() {
   var constCfonig = {
    MAX_NUM : 100,
    MIN_NUM: 1,
    COUNT: 1
   }
   return {
   get: function(name) {
    return constCfonig[name] ? constCfonig[name]: null
   }
  }
})()
var count  = constConfig.get('COUNT') // count =1

此时上面的变量就无法被用户修改了。

tips: 这里的变量大写是C语言的代码规范。

惰性单例

什么是惰性单例? 惰性单例: 在项目使用时才创建的实例,即延迟创建的实例。


// 步骤一 创建单体实例的方法
MyNamespace.Singleton = (function() {

  function constructor() { // All of the normal singleton code goes here.
    // Private members.
    var privateAttribute1 = false;
    var privateAttribute2 = [1, 2, 3];
  
    function privateMethod1() {
      ...
    }
    function privateMethod2(args) {
      ...
    }

    return { // Public members.
      publicAttribute1: true,
      publicAttribute2: 10,
    
      publicMethod1: function() {
        ...
      },
      publicMethod2: function(args) {
        ...
      }
    }
  }
})()

// 步骤二

MyNamespace.Singleton = (function() {
  
  function constructor() {
 // 上方的单体方法都在construtor 中.
    ...
  }
  
  return {
    getInstance: function() {
      // Control code goes here.
    }
  }
})()

// 步骤三
MyNamespace.Singleton = (function() {
  
  var uniqueInstance; // 创建私有变量保证单例执行
  
  function constructor() { 
    //  所有上方单例代码都保存在此处
    ...
  }
  //  使用惰性模式 创建的单例的调用方法变为 Singleton.getInstance().methodName()
  return {
    getInstance: function() {
      if(!uniqueInstance) { // 如果单例不存在就创建单例.
        uniqueInstance = constructor();
      }
      return uniqueInstance;
    }
  }
})()

此时上面使用单例的方法或者获取单例的方法变为了 Singleton.getInstance().methodName()。

tips: 上面的方法利用了闭包形成了真正的私有化单例,外部无权修改内部方法,达到变量方法的私有化。

一个实际的例子

使用单例模式封装一个兼容ie的ajax方法

此时我们应该考虑使用单例进行ajax 封装在单例中进行分支切换。

// 使用分支创建ajax 对象  如果要兼容老旧的浏览器使用ajax,那就可以用这种技术了
var SimpleXhrFactory = (function() {
  
  // The three branches.
  var standard = {
    createXhrObject: function() {
      return new XMLHttpRequest();
    }
  };
  var activeXNew = {
    createXhrObject: function() {
      return new ActiveXObject('Msxml2.XMLHTTP');
    }
  };
  var activeXOld = {
    createXhrObject: function() {
      return new ActiveXObject('Microsoft.XMLHTTP');
    }
  };
  
})();
/* SimpleXhrFactory singleton, step 2. */
var SimpleXhrFactory = (function() {
  
  // The three branches.
  var standard = {
    createXhrObject: function() {
      return new XMLHttpRequest();
    }
  };
  var activeXNew = {
    createXhrObject: function() {
      return new ActiveXObject('Msxml2.XMLHTTP');
    }
  };
  var activeXOld = {
    createXhrObject: function() {
      return new ActiveXObject('Microsoft.XMLHTTP');
    }
  };
  
  // To assign the branch, try each method; return whatever doesn't fail.
  var testObject;
  try {
    testObject = standard.createXhrObject();
    return standard; // Return this if no error was thrown.
  }
  catch(e) {
    try {
      testObject = activeXNew.createXhrObject();
      return activeXNew; // Return this if no error was thrown.
    }
    catch(e) {
      try {
        testObject = activeXOld.createXhrObject();
        return activeXOld; // Return this if no error was thrown.
      }
      catch(e) {
        throw new Error('No XHR object found in this environment.');
      }
    }
  }

})()

tips: 这里使用了简单工厂模式来进行了不同ajax的适配

思考题?

如何设计一个可拓展的单例模式库?Jquery是如何进行代码拓展与重写的。

每日一道算法题

答案会在下期公布。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-12-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 微瞰技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 大话设计模式(一)- 单例模式
    • 命名空间
      • 模块化
        • 创建小型代码库
          • 静态变量存储器
            • 惰性单例
              • 一个实际的例子
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档