代理模式的关键是,当客户不方便直接访问一个对象或者不满足需要的时候,提供一个替身对象来控制对这个对象的访问,客户实际上访问的是替身对象。替身对象对请求做出一些处理之后,再把请求转交给本体对象。

代理模式类图:

在上面类图中,代理模式所涉及的角色有三个:

抽象主题角色(Person):声明了真实主题和代理主题的公共接口,这样一来在使用真实主题的任何地方都可以使用代理主题。

代理主题角色(Friend):代 理主题角色内部含有对真实主题的引用,从而可以操作真实主题对象;代理主题角色负责在需要的时候创建真实主题对象;代理角色通常在将客户端调用传递到真实 主题之前或之后,都要执行一些其他的操作,而不是单纯地将调用传递给真实主题对象。例如这里的PreBuyProduct和PostBuyProduct 方法就是代理主题角色所执行的其他操作。

真实主题角色(RealBuyPerson):定义了代理角色所代表的真是对象。

附:在实际开发过程中,我们在客户端添加服务引用的时候,在客户程序中会添加一些额外的类,在客户端生成的类扮演着代理主题角色,我们客户端也是直接调用这些代理角色来访问远程服务提供的操作。这个是远程代理的一个典型例子。

先看一下C#的代理模式:

namespace 代理模式
{
class Program
{
static void Main(string[] args)
{
SchoolGirl jiaojiao = new SchoolGirl();
jiaojiao.Name = "李娇娇"; Proxy daili = new Proxy(jiaojiao); daili.GiveDolls();
daili.GiveFlowers();
daili.GiveChocolate(); Console.Read();
}
} //送礼物
interface GiveGift
{
void GiveDolls();
void GiveFlowers();
void GiveChocolate();
} class Proxy : GiveGift
{
Pursuit gg;
public Proxy(SchoolGirl mm)
{
gg = new Pursuit(mm);
} public void GiveDolls()
{
gg.GiveDolls();
} public void GiveFlowers()
{
gg.GiveFlowers();
} public void GiveChocolate()
{
gg.GiveChocolate();
}
} class Pursuit : GiveGift
{
SchoolGirl mm;
public Pursuit(SchoolGirl mm)
{
this.mm = mm;
}
public void GiveDolls()
{
Console.WriteLine(mm.Name + " 送你洋娃娃");
} public void GiveFlowers()
{
Console.WriteLine(mm.Name + " 送你鲜花");
} public void GiveChocolate()
{
Console.WriteLine(mm.Name + " 送你巧克力");
}
} class SchoolGirl
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
}
}

js模拟高级语言的代理模式:

var SchoolGirl = function(name){
this.name = name;
}; var Pursuit = function(mm){
this.mm = mm;
};
Pursuit.prototype.giveDolls = function(){
alert(this.mm.name + '送你洋娃娃');
};
Pursuit.prototype.giveFlowers = function(){
alert(this.mm.name + '送你鲜花');
};
Pursuit.prototype.giveChocolate = function(){
alert(this.mm.name + '送你巧克力');
}; var Proxy = function(mm){
this.gg = new Pursuit(mm);
};
Proxy.prototype.giveDolls = function(){
this.gg.giveDolls();
};
Proxy.prototype.giveFlowers = function(){
this.gg.giveFlowers();
};
Proxy.prototype.giveChocolate = function(){
this.gg.giveChocolate();
}; //调用:
var jiaojiao = new SchoolGirl();
jiaojiao.name = "李娇娇"; var daili = new Proxy(jiaojiao); daili.giveDolls();
daili.giveFlowers();
daili.giveChocolate();

js语言特性的代理模式:

var Flower = function(){};

    var Pursuit = {
sendFlower:function(target){
var flower = new Flower();
target.receiveFlower(flower);
}
}; var Proxy = {
sendFlower:function(target){
Pursuit.sendFlower(target);
}
}; var SchoolGirl = {
receiveFlower:function(flower){
console.log('收到花' + flower);
}
}; //调用:
Proxy.sendFlower(SchoolGirl);

js虚拟代理实现图片预加载:

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:Users/svenzeng/Desktop/loading.gif');
img.src = src;
}
}
})(); //调用:
proxyImage.setSrc('http://imgcache.qq.com/music/photo/k/000GGDys0yAonk.jpg');

js缓存代理实现计算器:

//计算乘积
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 = a + arguments[i];
}
return a;
}; //创建缓存代理工厂
var createProxyFactory = function(fn){
var cache = {};
return function(){
var args = [].join.call(arguments,',');
if(args in cache){
return cache[args];
}
return cache[args] = fn.apply(this,arguments);
}
}; //调用:
var proxyMult = createProxyFactory(mult),
proxyPlus = createProxyFactory(plus); alert(proxyMult(1,2,3,4)); //
alert(proxyMult(1,2,3,4)); //
alert(proxyPlus(1,2,3,4)); //
alert(proxyPlus(1,2,3,4)); //

总结:代理模式包括许多小分类,在js开发中最常用的是虚拟代理和缓存代理。虽然代理模式非常有用,但我们在编写业务的时候,往往不需要去预先猜测是否需要使用代理模式。当真正发现不方便直接访问某个对象的时候,再编写代理也不迟。

js代理模式的更多相关文章

  1. JS 代理模式

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  2. JS代理模式实现图片预加载

    ---恢复内容开始--- 刚刚说了懒加载,现在我们来搞搞预加载吧 预加载的核心: 图片等静态资源在使用前提前请求. 资源后续使用可以直接从缓存中加载,提升用户体验. 几个误区: 预加载不是为了减少页面 ...

  3. js设计模式系列之(一)请节约你的请求-代理模式

    What’s the proxy pattern? 代理模式其实就是将违反单一性原则的类给抽离出来,尽量满足开放和封闭的原则. 相当于一个类的行为只是一种,但是你可以给这个类添加额外的行为.比如: 一 ...

  4. JS设计模式(3)代理模式

    什么是代理模式? 情景:小明追女生 A 非代理模式:小明 =花=> 女生A 代理模式:小明 =花=> 让女生A的好友B帮忙 =花=> 女生A 定义:为其他对象提供一种代理以控制对这个 ...

  5. js设计模式——1.代理模式

    js设计模式——1.代理模式 以下是代码示例 /*js设计模式——代理模式*/ class ReadImg { constructor(fileName) { this.fileName = file ...

  6. js设计模式总结-代理模式

    代理模式 解决哪一类问题 从字面意思上理解,代理模式解决对一个对象的直接访问,这种直接访问可能是"不方便"的,所谓"不方便"可能是直接访问成本比较大(在前端领域 ...

  7. 大熊君说说JS与设计模式之------代理模式Proxy

    一,总体概要 1,笔者浅谈 当我们浏览网页时,网页中的图片有时不会立即展示出来,这就是通过虚拟代理来替代了真实的图片,而代理存储了真实图片的路径和尺寸,这就是代理方式的一种. 代理模式是比较有用途的一 ...

  8. js设计模式(9)---代理模式

    0.前言 KG.PP被交易到了布鲁克林篮网,我的心情很复杂,一方面为他们不能终老celtics感到惋惜,另一方面为他们能够再次冲击总冠军感到高兴.从07年以来,作为一个铁杆celtics球迷,他们给我 ...

  9. JS 设计模式六 -- 代理模式

    概念 为一个对象提供一个代用品或占位符,以便控制对它的访问. 当客户不方便直接访问一个对象的时候,需要提供一个替身对象来控制对这个对象的访问. 替身对象对请求做出一些处理之后, 再把请求转交给本体对象 ...

随机推荐

  1. 巨蟒django之权限8:排序&&菜单展开权限归属

    1.权限控制的流程+表结构 内容回顾: wsgi:socket进行收发消息 中间件:(超级重点的面试题)在全局范围内控制django的输入和输出的一个钩子,处理输入和输出说白了就是处理请求和响应req ...

  2. Python 编码(一)— Python3

    Unicode 什么是 Unicode 标准 unicode 标准 Unicode 为每个字符提供了一个独特的数字,并且跨平台.设备.应用或者编程语言都是通用的. -- 来自 http://unico ...

  3. PHP heredoc 用法

    php 中的 heredoc技术是php用来引用字符串的一种方式.在phpwind中巧妙的运用了这个技术,实现了逻辑代码和界面设计的分离. 语法: 1. 使用操作符  “<<<” 2 ...

  4. Docker + ElasticSearch + Node.js

    最近有空就想研究下ElasticSearch. 此篇文章用来记录研究过程.备注:需要有一定的docker基础,ElasticSearch的基本概念 Docker安装ElasticSearch 首先,就 ...

  5. 在Nuxt中使用 Highcharts

    npm进行highchars的导入,导入完成后就可以进行highchars的可视化组件开发了 npm install highcharts --save 1.components目录下新建一个char ...

  6. element-ui中下拉菜单中的@click事件不会触发的问题

    只需要将@click=“fun()”改为@click.native=“fun()”,即可监听下拉菜单的点击事件. 如图所示: 嗯,就酱~

  7. 通过配置rinetd来实现ECS跳转访问非外网连接的mongodb

    跳转的原理通用,不单单针对mongo,其他需求应用也可以使用这种方式   生成环境中的mongodb迁移到了阿里云上的mongodb,由于机制的问题,mongodb不能直接被外网访问,故此采用的办法为 ...

  8. pycharm中导入自写模块时,模块下出现红线

    问题描述: 在pycharm中导入自己写的模块时,得不到智能提示,并在模块名下出现下红线,但是代码可以执行,错误提示为下图所示: 原因:出现 以上情况,是因为文件目录设置的问题,pycharm中的最上 ...

  9. Java并发—简介与线程创建

    程序.进程和线程 程序:一段静态的代码,一组指令的有序集合,不运行的话只是一堆代码. 程序并不能单独执行,只有将程序加载到内存中,系统为他分配资源后才能够执行,这种执行的程序称之为进程.也就是说进程是 ...

  10. K-M-P

    分段K-M-P 只需要记录上一段已经匹配了的长度,再接着从匹配下一段就可以了.