分享
 
 
 

代理(Proxy)模式

王朝other·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

代理模式概念

代理模式是对象的结构模式[GOF95]。代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。

代理模式的英文叫做Proxy或Surrogate,中文都可译成"代理"。所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动。 在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

代理的种类

如果按照使用目的来划分,代理有以下几种:

远程(Remote)代理、为一个位于不同的地址空间的对象提供一个局域代表对象。这个不同的地址空间可以是在本机器中,亦可是在另一台机器中。远程代理又叫做大使(Ambassador)。

虚拟(Virtual)代理、根据需要创建一个资源消耗较大的对象,使得此对象只在需要时才会被真正创建。本章下面给出一个加载图像的例子说明虚拟代理的使用。

Copy-on-Write代理、虚拟代理的一种。把复制(克隆)拖延到只有在客户端需要时,才真正采取行动。

保护(Protect or Access)代理、控制对一个对象的访问,如果需要可以给不同的用户提供不同级别的使用权限。

Cache代理、为某一个目标操作的结果提供临时的储存空间,以便多个客户端可以共享这些结果。

防火墙(Firewall)代理、保护目标,不让恶意用户接近。

同步化(Synchronization)代理、使几个用户能够同时使用一个对象而没有冲突。

智能引用(Smart Reference)代理、当一个对象被引用时,提供一些额外的操作,比如将对此对象调用的次数记录下来等。

在所有种类的代理模式中,虚拟(Virtual)代理、远程(Remote)代理、智能引用代理(Smart Reference Proxy)和保护(Protect or Access)代理是最为常见的代理模式种类。

在有些讲解设计模式的书籍中(如[GRAND98]),不同的代理模式被独立划分出来,以强调它们的不同;在另外的书籍中,所有的代理模式都放在一些讲解,以强调它们的共同点。本文采取[YAN02]中的讲解方式,首先将所有的代理模式放到一个地方进行理论上的讲解,然后针对不同的类型提供不同的例子,进行实现方式上的讲解。

远程代理的例子:Achilles

Achilles是一个用来测试网站的安全性能的工具软件。Achilles相当于位于客户端的一个桌面代理服务器,在一个HTTP过程里起到一个中间人的作用,但是Achilles与通常的代理服务器又有不同。

一个通常的HTTP代理软件会将一个客户端的HTTP数据包转发给网络服务器。Achilles则截获双向的通讯数据,使得Achilles软件的用户可以改变来自和发往网络服务器的数据。比如,在一个正常的SSL联系中,一个通常的代理服务器会转发通讯使得双方可以商议SSL连接;而Achilles则不同。当Achilles处于截取状态时,它会向客户端假装是服务器,同时向真正的服务器假装是浏览器,在两端商议SSL通讯。Achilles可以破解加密的数据,给Achilles的用户显示已经解密的内容,并且允许用户更改处于通讯过程中的数据。

下面显示的是Achilles软件在运行时的情况:

读者可以免费从http://www.digizen-security.com/projects.html下载这个软件。

显然,对于浏览器而言,Achilles所代理的是远程的网络服务器。Achilles的工作方式便是远程代理模式的应用。

Windows的快捷方式:代理的例子

Windows系统提供快捷方式(Shortcut),可以使任何对象同时出现在多个地方而不必修改原对象。对快捷方式的调用完全与对原对象的调用一样,换言之,快捷方式对客户端是完全透明的。

比如上面的图标便是Windows服务的代理。所有的快捷方式都有一个小的箭头在图标的左下方。这就是说,用户可以区分原对象和指向原对象的代理。如果原对象被删除,则快捷方式虽然仍可存在,但是在调用时会给出错误。

在下面的图中,一个名为link1的快捷方式是一个名为explorer.exe的文件的代理。当用户启动这个快捷方式时,link1会把用户的调用传递给它所代理的explorer.exe文件。

在Macintosh里面有Alias,在Unix里面有link,它们都和Windows的便捷方式一样,是代理模式的应用。

代理模式的结构

代理模式所涉及的角色有:

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

代理主题(Proxy)角色、首先代理主题角色内部含有对真实主题的引用,从而可以在任何时候操作真实主题对象;

其次代理主题角色提供一个与真实主题角色相同的接口,以便可以在任何时候都可以替代真实主体;

第三,控制对真实主题的引用,负责在需要的时候创建真实主题对象(和删除真实主题对象);

第四,代理角色通常在将客户端调用传递给真实的主题之前或者之后都要执行某个操作,而不是单纯地将调用传递给真实主题对象。

真实主题角色、定义了代理角色所代表的真实对象。

下面给出一个非常简单的示意性实现,请见实现的类图:

下面给出的是抽象主题角色的示意性源代码,可以看出,这个角色规定所有的主题对象必须实现request()方法:

Public MustInherit Class Subject

Public MustOverride Sub Request()

End Class

代码清单1、主题角色的源代码。

下面就是具体主题角色的示意性源代码。这里仅仅给出了request()方法的示意性实现:

Public Class RealSubject

Inherits Subject

Public Sub RealSubject()

System.Console.WriteLine("RealSubject object is created.")

End Sub

Public Overrides Sub Request()

System.Console.WriteLine("RealSubject.Request().")

End Sub

End Class

代码清单2、真实主题角色的源代码。

下面是代理主题角色的源代码。可以看出,代理主题除了将所有的请求原封不动地委派给真实主题角色之外,还在委派之前和之后分别执行一个preRequest()操作和一个postRequest()操作:

Public Class ProxySubject

Inherits Subject

Private rs As RealSubject

Public Sub New()

rs = New RealSubject()

End Sub

Private Sub PreRequest()

System.Console.WriteLine("Before passing request to RealSubject.")

End Sub

Private Sub PostRequest()

System.Console.WriteLine("After passing request to RealSubject.")

End Sub

Public Overrides Sub Request()

PreRequest()

rs.Request()

PostRequest()

End Sub

End Class

代码清单3、代理主题的源代码。

在使用代理主题时,注意要将变量的明显类型声明为抽象主体的类型,而将其真实类型设置为代理主题类型。请见下面的例子:

Private subj As Subject

. . .

subj = New ProxySubject()

subj.Request()

代码清单4、怎样调用代理主题。

在运行时,会打印出下面的信息:

Before passing request to RealSubject.

RealSubject.Request().

After passing request to RealSubject.

代码清单5、怎样调用代理主题。

从上面的代理主题类的示意性源代码可以看出代理模式是怎样工作的。首先,代理主题并不改变主题的接口,因为模式的用意是不让客户端感觉到代理的存在;其次,代理使用委派将客户端的调用委派给真实的主题对象,换言之,代理主题起到的是一个传递请求的作用;第三,代理主题在传递请求之前和之后都可以执行特定的操作,而不是单纯传递请求。

代理模式的时序

类图是静态的并不适合于反映出模式在运行时的特性;时序图更能够反映出模式的活动情况。下面就是所讨论的代理模式的时序图:

从上面的时序图可以看出,客户端向代理主题发出请求,代理主题在接到请求的同时,执行了一个PreRequest()操作,然后才把请求传递给真实主题。在真实主题将请求返回后,代理主题又执行了一个PostRequest()操作,才将控制返回给客户端。参见下面的对象图。

与客户端直接向真实主题发出请求的情况相比,使用代理主题的显著好处是系统提供了向真实主题传递客户端请求的控制。代理主题可以在传递向真实主题传递客户端请求之前执行特定的操作,并决定是否将请求传递给真实主题;代理主题可以在向真实主题传递客户端请求之后执行另外一种操作,比如将客户端请求计数等。有可能客户端根本没有直接向真实主题提出请求的许可,而代理主题具有这种许可,因此代理主题可以在执行PreRequest()操作后决定是否再传递请求,等等。总之,代理模式将一个中间层插入到客户端和主题角色之间,从而提供了许多的灵活性。

代理模式的长处和短处

根据代理的种类代理模式有不同的特点。

远程代理

好处是系统可以将网络的细节隐藏起来,使得客户端不必考虑网络的存在。客户完全可以认为被代理的对象是局域的而不是远程的,而代理对象承担

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有