美文网首页
JS设计模式四:代理模式

JS设计模式四:代理模式

作者: 5d18ee6b5b1c | 来源:发表于2018-01-23 21:40 被阅读0次

代理模式简述

代理是一个对象,跟本体对象具有相同的接口,以此达到对本体对象的访问控制。

简单言之,本体对象只注重业务逻辑的实现,代理则控制本体对象的实例化(何时实例化、何时被使用)。

代理模式的优点在于:代理对象可以代替本体对象被实例化,此时本体对象未真正实例化,等到合适时机再实例化。

代理模式可以延迟创建开销很大的本体对象,他会把本体的实例化推迟到有方法被调用时。

一个简单的例子

// 声明女孩对象
var girl = function (name) {
    this.name = name;
};
// 声明男孩对象
var boy = function (girl) {
    this.girl = girl;
    this.sendGift = function (gift) {
        alert("Hi " + girl.name + ", 男孩送你一个礼物:" + gift);
    }
};
// 声明代理对象
var proxyObj = function (girl) {
    this.girl = girl;
    this.sendGift = function (gift) {
        (new boy(girl)).sendGift(gift); // 替dudu送花咯
    }
};
var proxy = new proxyObj(new girl("花花"));
proxy.sendGift("999朵玫瑰");

如上代码,girl是一个被送礼物的对象,boy是送礼物的对象,他保存了girl这个属性,还有一个送礼物的方法sendGift,然后他通过proxyObj去完成这件事,proxyObj就是代理,他把boy的礼物送给了girl,因此proxyObj同样需要保存girl的属性,同时也有sendGift方法,该方法实例化本体对象boy并调用了boy的sendGift方法,完成了boy送girl礼物的这个过程。

实战一:图片加载

在前端开发中,使用图片是非常常见的场景,如果直接给img标签设置src属性,如果图片过大,或网速比较慢,图片在加载过程中会有一段时间的空白,用户体验不好。

传统的解决方案

传统的解决方法是:在图片未加载完成之前,使用一个loading图标作为占位符,等图片完成加载后,再使用真实的图片地址替代loading图标。如下:

// 不使用代理的预加载图片函数如下
var myImage = (function(){
    var imgNode = document.createElement("img");
    document.body.appendChild(imgNode);
    var img = new Image();
    img.onload = function(){
        imgNode.src = this.src;
    };
    return {
        setSrc: function(src) {
            imgNode.src = "http://img.lanrentuku.com/img/allimg/1212/5-121204193R0.gif";
            img.src = src;
        }
    }
})();
// 调用方式
myImage.setSrc("https://www.baidu.com/img/bd_logo1.png");

如上代码,这是使用一般的编码方式实现图片的预加载技术的方案,首先创建imgNode元素,然后调用myImage.setSrc该方法的时候,先给图片一个预加载图片,当图片加载完的时候,再给img元素赋值。

这种方案是可以实现功能,但也有比较明显的缺陷:耦合性太高,myImage函数违背了面向对象设计原则中的单一职责原则,同时完成了创建img,设置loading加载状态等多个任务。

此时就可以使用代理模式来实现~~~

代理模式解决方案

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("http://img.lanrentuku.com/img/allimg/1212/5-121204193R0.gif");
        img.src = src;
        }
    }
})();
// 调用方式
ProxyImage.setSrc("https://www.baidu.com/img/bd_logo1.png");

如上代码,myImage 函数只负责做一件事,创建img元素加入到页面中,其中的加载loading图片交给代理函数ProxyImage 去做,当图片加载成功后,代理函数ProxyImage 会通知及执行myImage 函数的方法,同时当以后不需要代理对象的话,我们直接可以调用本体对象的方法即可。

代理模式跟本体对象具有相同的对外接口,有两个好处:
一、用户可以放心地请求代理,不需要了解代理的实现过程,只要结果符合预期即可。如果不需要代理对象了,可以换成调用本体对象的该方法
二、在任何使用本体对象的地方,都可以使用代理替换。

最后,强调一点,主体对象跟代理对象也可以都返回一个匿名函数,这样也认为他们具有相同的接口。

实战二:缓存代理

对第一次运行的结果进行缓存,当再一次运行相同运算的时候,直接从缓存里面取,避免重复运算,如果运算非常复杂的话,对性能很耗费,那么使用缓存对象可以提高性能。以下是一个简单的例子:

var mult = function(){
    var a = 1;
    for(var i = 0,ilen = arguments.length; i < ilen; i+=1) {
        a = a*arguments[i];
    }
    return a;
};
// 计算加法
var plus = function(){
    var a = 0;
    for(var i = 0,ilen = arguments.length; i < ilen; i+=1) {
        a += arguments[i];
    }
    return a;
}
// 代理函数
var proxyFunc = function(fn) {
    var cache = {};  // 缓存对象
    return function(){
        var args = Array.prototype.join.call(arguments,',');
        if(args in cache) {
            return cache[args];   // 使用缓存代理
        }
        return cache[args] = fn.apply(this,arguments);
    }
};
var proxyMult = proxyFunc(mult);
console.log(proxyMult(1,2,3,4)); // 24
console.log(proxyMult(1,2,3,4)); // 缓存取 24

var proxyPlus = proxyFunc(plus);
console.log(proxyPlus(1,2,3,4));  // 10
console.log(proxyPlus(1,2,3,4));  // 缓存取 10

如上代码就是网上常见的加法和乘法的运算。通过缓存代理,可以减少不必要的运算量。

相关文章

  • 前端设计模式

    JS设计模式一:工厂模式jS设计模式二:单例模式JS设计模式三:模块模式JS设计模式四:代理模式JS设计模式五:职...

  • 《JS设计模式》读书笔记(一)

    标签:JS 设计模式 《JS设计模式》读书笔记(二) 《JS设计模式》读书笔记(三) 《JS设计模式》读书笔记(四...

  • JS设计模式四:代理模式

    代理模式简述 代理是一个对象,跟本体对象具有相同的接口,以此达到对本体对象的访问控制。 简单言之,本体对象只注重业...

  • 实习第七十四天(设计模式)

    参考 《JS设计模式》读书笔记(二) 《JS设计模式》读书笔记(三) 《JS设计模式》读书笔记(四) 《JS设计模...

  • 2021-11-17 - 学习记录

    适配器模式 - js: 代理模式 - js 组合模式 - js

  • JS设计模式-代理模式

    虚拟代理 虚拟代理是把一些开销很大的对象,延迟到真正需要它的时候才去创建执行 图片懒加载 合并http请求 如果有...

  • JS设计模式-代理模式

    介绍 使用者无权访问目标对象 中间加代理,通过代理做授权和控制比如说公司的内网,当我们在家的时候也是需要一个代理才...

  • js代码题

    js对象的深度克隆 js数组去重 js常用设计模式的实现思路,单例,工厂,代理,装饰,观察者模式等

  • JavaScript设计模式四(代理模式)

    JavaScript设计模式四(代理模式) 代理模式的定义: 代理模式是为一个对象提供一个代用品或者占位符,以便对...

  • Mybatis代理设计模式(Proxy)与编程实现原理

    最易懂设计模式解析适配器设计模式模板方法设计模式Mybatis多级代理 1. 认识代理模式 1.1 模式定义 给某...

网友评论

      本文标题:JS设计模式四:代理模式

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