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

代理模式类图:

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

抽象主题角色(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. 第五课 nodejs 路由实现并处理请求作出响应

    1创建一个http Server 文件server.js var http = require('http');var url = require('url');function start(rout ...

  2. Git 命令行帮助

    Git usage: git [--version] [--help] [-C <path>] [-c name=value] [--exec-path[=<path>]] [ ...

  3. Asp.Net MVC anti-forgery token的问题:nameidentifier or identityprovider not present

    当使用ClaimsIdentity的时候,Asp.Net MVC在生成AntiForgeryToken的时候会默认使用User.Identity中两种ClaimsType的值:NameIdentifi ...

  4. 浅析僵尸进程&孤儿进程

    0x01 前言 此文出自:https://www.cnblogs.com/Anker/p/3271773.html 博文主要用unix/linux举例,但道理没问题的同样有助于在Python中理解僵尸 ...

  5. 斯坦福大学Andrew Ng - 机器学习笔记(6) -- 聚类 & 降维

    大概用了一个月,Andrew Ng老师的机器学习视频断断续续看完了,以下是个人学习笔记,入门级别,权当总结.笔记难免有遗漏和误解,欢迎讨论. 鸣谢:中国海洋大学黄海广博士提供课程视频和个人笔记,在此深 ...

  6. Activity重要函数

    一.onConfigurationChanged 与 android:configChanges Lists configuration changes that the activity will ...

  7. RedHat安装yum+配置国内yum源

      新安装了redhat6.5安装后,登录系统,使用yum update 更新系统.提示: This system is not registered to Red Hat Subscription ...

  8. MongoDB学习笔记—常用命令

    这里记录一下MongoDB常用的命令 数据库相关 创建数据库 use DATABASE_NAME 如果数据库不存在,则创建数据库,否则切换到指定数据库. 删除数据库:切换到要删除的数据库下,执行命令即 ...

  9. Java替换字符串中的占位符

    在开发中,会有动态配置字符串其中的某些字符,如何使用字符中的占位符,并且在代码动态替换占位符实现动态配置字符串! 1.定义字符串时,再string文件添加字符串: 注意!记得要在字符文件中加上这些: ...

  10. 0607am抽象类&接口&析构方法&tostring&小知识点

    /*class ren{ public static $color;//静态 static function () { ren::$color; self::$color;//self只能写在类里面, ...