学习JavaScript设计模式(代理模式)


Posted in Javascript onDecember 03, 2015

代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问
代理模式的用处(个人理解):为了保障当前对象的单一职责(相对独立性),而需要创建另一个对象来处理调用当前对象之前的一些逻辑以提高代码的效率、状态判断等。
代理模式中最常用的是虚拟代理缓存代理

一、虚拟代理
虚拟代理是把一些开销很大的对象,延迟到真正需要它的时候才去创建执行
示例: 虚拟代理实现图片预加载

// 图片加载函数
var myImage = (function(){
  var imgNode = document.createElement("img");
  document.body.appendChild(imgNode);

  return {
    setSrc: function(src) {
      imgNode.src = src;
    }
  }
})();

// 引入代理对象
var proxyImage = (function(){
  var img = new Image;
  img.onload = function(){
    // 图片加载完成,正式加载图片
    myImage.setSrc( this.src );
  };
  return {
    setSrc: function(src){
      // 图片未被载入时,加载一张提示图片
      myImage.setSrc("file://c:/loading.png");
      img.src = src;
    }
  }
})();

// 调用代理对象加载图片
proxyImage.setSrc( "http://images/qq.jpg");

示例: 虚拟代理合并HTTP请求
假设一个功能需要频繁的进行网络请求,这会造成相当大的开销,解决方案是通过一个代理函数来收集一段时间之内的请求,一次性发给服务器。
例如:做一个文件同步的功能,当我们选中一个文件时,就同步到另外一台备用服务器上

// 文件同步函数
var synchronousFile = function( id ){
  console.log( "开始同步文件,id为:" + id );
}
// 使用代理合并请求
var proxySynchronousFile = (function(){
  var cache = [], // 保存一段时间内需要同步的ID
    timer; // 定时器指针

  return function( id ){
    cache[cache.length] = id;
    if( timer ){
      return;
    }

    timer = setTimeout( function(){
      proxySynchronousFile( cache.join( "," ) ); // 2s 后向本体发送需要同步的ID集合
      clearTimeout( timer ); // 清空定时器
      timer = null;
      cache = []; // 晴空定时器
    },2000 );
  }
})();

// 绑定点击事件
var checkbox = document.getElementsByTagName( "input" );

for(var i= 0, c; c = checkbox[i++]; ){
  c.onclick = function(){
    if( this.checked === true ){
      // 使用代理进行文件同步
      proxySynchronousFile( this.id );
    }
  }
}

二、 缓存代理
缓存代理可以为一些开销大的运算结果提供暂时的存储,在下次运算时,如果传递进来的参数跟之前一致,则可以返回前面的运算结果。
示例: 为乘法、加法等创建缓存代理

// 计算乘积
var mult = function(){
  var a = 1;
  for( var i = 0, l = arguments.length; i < l; i++){
    a = a * arguments[i];
  }
  return a;
};
// 计算加和
var plus = function () {
 var a = 0;
  for( var i = 0, l = arguments.length; i < l; i++ ){
    a += arguments[i];
  }
  return a;
};
// 创建缓存代理的工厂
var createProxyFactory = function( fn ){
  var cache = {}; // 缓存 - 存放参数和计算后的值
  return function(){
    var args = Array.prototype.join.call(arguments, "-");
    if( args in cache ){ // 判断出入的参数是否被计算过
      console.log( "使用缓存代理" );
      return cache[args];
    }
    return cache[args] = fn.apply( this, arguments );
  }
};
// 创建代理
var proxyMult = createProxyFactory( mult ),
  proxyPlus = createProxyFactory( plus );

console.log( proxyMult( 1, 2, 3, 4 ) ); // 输出: 24
console.log( proxyMult( 1, 2, 3, 4 ) ); // 输出: 缓存代理 24
console.log( proxyPlus( 1, 2, 3, 4 ) ); // 输出: 10
console.log( proxyPlus( 1, 2, 3, 4 ) ); // 输出: 缓存代理 10

以上三个示例为大家详细介绍了javascript代理模式,希望对大家的学习有所帮助。

Javascript 相关文章推荐
老鱼 浅谈javascript面向对象编程
Mar 04 Javascript
IE下使用cloneNode注意事项分享
Nov 22 Javascript
jQuery实现可用于博客的动态滑动菜单
Mar 09 Javascript
AngularJs  Creating Services详解及示例代码
Sep 02 Javascript
jQ处理xml文件和xml字符串的方法(详解)
Nov 22 Javascript
一文让你彻底搞清楚javascript中的require、import与export
Sep 24 Javascript
vue中axios的封装问题(简易版拦截,get,post)
Jun 15 Javascript
js 实现在2d平面上画8的方法
Oct 10 Javascript
Node 搭建一个静态资源服务器的实现
May 20 Javascript
vue 获取视频时长的实例代码
Aug 20 Javascript
详解小程序如何改变onLoad的执行时机
Nov 01 Javascript
vue 手机物理监听键+退出提示代码
Sep 09 Javascript
全面解析Bootstrap图片轮播效果
Dec 03 #Javascript
谈谈基于iframe、FormData、FileReader三种无刷新上传文件的方法
Dec 03 #Javascript
解决JavaScript数字精度丢失问题的方法
Dec 03 #Javascript
Javascript实现检测客户端类型代码封包
Dec 03 #Javascript
javascript学习小结之prototype
Dec 03 #Javascript
简单实现JS对dom操作封装
Dec 02 #Javascript
jQuery实现获取绑定自定义事件元素的方法
Dec 02 #Javascript
You might like
php 设计模式之 单例模式
2008/12/19 PHP
php批量缩放图片的代码[ini参数控制]
2011/02/11 PHP
PHP设计模式之委托模式定义与用法简单示例
2018/08/13 PHP
web 页面分页打印的实现
2009/06/22 Javascript
JavaScript对象链式操作代码(jquery)
2010/07/04 Javascript
自定义jQuery选项卡插件实例
2013/03/27 Javascript
Javascript基础教程之for循环
2015/01/18 Javascript
JavaScript获取元素尺寸和大小操作总结
2015/02/27 Javascript
JS使用cookie实现DIV提示框只显示一次的方法
2015/11/05 Javascript
浅析Bootstrap缩略图组件与警示框组件
2016/04/29 Javascript
使用开源工具制作网页验证码的方法
2016/10/17 Javascript
jQuery 判断元素整理汇总
2017/02/28 Javascript
Vue2单一事件管理组件通信
2017/05/09 Javascript
jquery如何实现点击空白处隐藏元素
2017/12/05 jQuery
如何从零开始利用js手写一个Promise库详解
2018/04/19 Javascript
Electron 如何调用本地模块的方法
2019/02/01 Javascript
vue路由对不同界面进行传参及跳转的总结
2019/04/20 Javascript
javascript将扁平的数据转为树形结构的高效率算法
2020/02/27 Javascript
js实现Element中input组件的部分功能并封装成组件(实例代码)
2021/03/02 Javascript
[05:05]第三天的dota2
2013/07/29 DOTA
[05:31]DOTA2英雄梦之声_第08期_莉娜
2014/06/23 DOTA
Python实现解析Bit Torrent种子文件内容的方法
2017/08/29 Python
python3实现二叉树的遍历与递归算法解析(小结)
2019/07/03 Python
python字符串查找函数的用法详解
2019/07/08 Python
python自动识别文本编码格式代码
2019/12/26 Python
python中pow函数用法及功能说明
2020/12/04 Python
纯CSS3实现的8种Loading动画效果
2014/07/05 HTML / CSS
使用CSS3设计地图上的雷达定位提示效果
2016/04/05 HTML / CSS
三星美国官网:Samsung美国
2017/02/06 全球购物
英国领先的名牌服装折扣零售商:Brown Bag Clothing
2019/01/08 全球购物
Columbia Sportswear法国官网:全球户外品牌
2020/09/25 全球购物
丧事主持词大全
2014/04/02 职场文书
勾股定理课后反思
2014/04/26 职场文书
宣传活动总结范文
2014/07/01 职场文书
出差报告格式模板
2014/11/06 职场文书
开国大典观后感
2015/06/04 职场文书