摘要
本文讨论了代理模式的概念、种类、长处和短处,以及在Visual Basic.NET(见文中)和C#语言中的实现(见附录),以及代理模式与其他设计模式的关系。
--------------------------------------------------------------------------------
目录
代理模式概念
代理的种类
远程代理的例子:Achilles
Windows的快捷方式:代理的例子
代理模式的结构
代理模式的时序
代理模式的长处和短处
模式的实现
代理模式与其它模式的关系
附录、C#代码
参考文献
--------------------------------------------------------------------------------
代理模式概念
代理模式是对象的结构模式[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软件在运行时的情况:

图1、Achilles运行的情况。
读者可以免费从http://www.digizen-security.com/projects.html下载这个软件。
显然,对于浏览器而言,Achilles所代理的是远程的网络服务器。Achilles的工作方式便是远程代理模式的应用。
--------------------------------------------------------------------------------
Windows的快捷方式:代理的例子
Windows系统提供快捷方式(Shortcut),可以使任何对象同时出现在多个地方而不必修改原对象。对快捷方式的调用完全与对原对象的调用一样,换言之,快捷方式对客户端是完全透明的。

图2、服务的快捷方式。
比如上面的图标便是Windows服务的代理。所有的快捷方式都有一个小的箭头在图标的左下方。这就是说,用户可以区分原对象和指向原对象的代理。如果原对象被删除,则快捷方式虽然仍可存在,但是在调用时会给出错误。
在下面的图中,一个名为link1的快捷方式是一个名为explorer.exe的文件的代理。当用户启动这个快捷方式时,link1会把用户的调用传递给它所代理的explorer.exe文件。

图3、一个快捷方式的例子。
在Macintosh里面有Alias,在Unix里面有link,它们都和Windows的便捷方式一样,是代理模式的应用。
--------------------------------------------------------------------------------
代理模式的结构
代理模式所涉及的角色有:
抽象主题角色、声明了真实主题和代理主题的共同接口,这样一来在任何可以使用真实主题的地方都可以使用代理主题。
代理主题(Proxy)角色、首先代理主题角色内部含有对真实主题的引用,从而可以在任何时候操作真实主题对象;
其次代理主题角色提供一个与真实主题角色相同的接口,以便可以在任何时候都可以替代真实主体;
第三,控制对真实主题的引用,负责在需要的时候创建真实主题对象(和删除真实主题对象);
第四,代理角色通常在将客户端调用传递给真实的主题之前或者之后都要执行某个操作,而不是单纯地将调用传递给真实主题对象。
真实主题角色、定义了代理角色所代表的真实对象。
下面给出一个非常简单的示意性实现,请见实现的类图:

图4、代理模式的结构图。
下面给出的是抽象主题角色的示意性源代码,可以看出,这个角色规定所有的主题对象必须实现request()方法:
[本文共有 2 页,当前是第 1 页] <<上一页 下一页>>