代理模式(Proxy Pattern)
——.NET设计模式系列之十四
Terrylee,2006年5月
摘要
在软件系统中,有些对象有时候由于跨越网络或者其他的障碍,而不能够或者不想直接访问另一个对象,如果直接访问会给系统带来不必要的复杂性,这时候可以在客户程序和目标对象之间增加一层中间层,让代理对象来代替目标对象打点一切。这就是本文要说的Proxy模式。
主要内容
1.例说Proxy模式
2.Proxy模式效果及实现要点
……
概述
在软件系统中,有些对象有时候由于跨越网络或者其他的障碍,而不能够或者不想直接访问另一个对象,如果直接访问会给系统带来不必要的复杂性,这时候可以在客户程序和目标对象之间增加一层中间层,让代理对象来代替目标对象打点一切。这就是本文要说的Proxy模式。
意图
为其他对象提供一种代理以控制对这个对象的访问。
结构图
生活中的例子
代理模式提供一个中介以控制对这个对象的访问。一张支票或银行存单是账户中资金的代理。支票在市场交易中用来代替现金,并提供对签发人账号上资金的控制。
使用银行存单例子的Proxy模式对象图
Proxy模式解说
在软件系统中,我们无时不在跨越障碍,当我们访问网络上一台计算机的资源时,我们正在跨越网络障碍,当我们去访问服务器上数据库时,我们又在跨越
数据库访问障碍,同时还有网络障碍。跨越这些障碍有时候是非常复杂的,如果我们更多的去关注处理这些障碍问题,可能就会忽视了本来应该关注的业务逻辑问
题,Proxy模式有助于我们去解决这些问题。我们以一个简单的数学计算程序为例,这个程序只负责进行简单的加减乘除运算:
复制
保存
/// <summary>
/// Author : Terrylee
/// From : http://terrylee.cnblogs.com
/// </summary>
public
class
Math
{
public
double
Add(double
x, double
y)
{
return
x + y;
}
public
double
Sub(double
x, double
y)
{
return
x - y;
}
public
double
Mul(double
x, double
y)
{
return
x * y;
}
public
double
Dev(double
x, double
y)
{
return
x / y;
}
}
如果说这个计算程序部署在我们本地计算机上,使用就非常之简单了,我们也就不用去考虑Proxy模式了。但现在问题是这个Math类并没有部署在
我们本地,而是部署在一台服务器上,也就是说Math类根本和我们的客户程序不在同一个地址空间之内,我们现在要面对的是跨越Internet这样一个网
络障碍:
这时候调用Math类的方法就没有下面那么简单了,因为我们更多的还要去考虑网络的问题,对接收到的结果解包等一系列操作。
复制
保存
/// <summary>
/// Author : Terrylee
/// From : http://terrylee.cnblogs.com
/// </summary>
public
class
App
{
public
static
void
Main()
{
Math math = new
Math();
// 对接收到的结果数据进行解包
double
addresult = math.Add(2, 3);
double
subresult = math.Sub(2, 3);
double
mulresult = math.Mul(2, 3);
double
devresult = math.Dev(2, 3);
}
}
为了解决由于网络等障碍引起复杂性,就引出了Proxy模式,我们使用一个本地的代理来替Math类打点一切,即为我们的系统引入了一层间接层,示意图如下
我们在MathProxy中对实现Math数据类的访问,让MathProxy来代替网络上的Math类,这样我们看到MathProxy就好像是本地Math类,它与客户程序处在了同一地址空间内:
复制
保存
/// <summary>
/// Author : Terrylee
/// From : http://terrylee.cnblogs.com
/// </summary>
public
class
MathProxy
{
private
Math math = new
Math();
// 以下的方法中,可能不仅仅是简单的调用Math类的方法
public
double
Add(double
x, double
y)
{
return
math.Add(x, y);
}
public
double
Sub(double
x, double
y)
{
return
math.Sub(x, y);
}
public
double
Mul(double
x, double
y)
{
return
math.Mul(x, y);
}
public
double
Dev(double
x, double
y)
{
return
math.Dev(x, y);
}
}
现在可以说我们已经实现了对Math类的代理,存在的一个问题是我们在MathProxy类中调用了原实现类Math的方法,但是Math并不一
定实现了所有的方法,为了强迫Math类实现所有的方法,另一方面,为了我们更加透明的去操作对象,我们在Math类和MathProxy类的基础上加上
一层抽象,即它们都实现与IMath接口,示意图如下:
示意性代码如下:
复制
保存
/// <summary>
/// Author : Terrylee
/// From : http://terrylee.cnblogs.com
/// </summary>
public
interface
IMath
{
double
Add(double
x, double
y);
double
Sub(double
x, double
y);
double
Mul(double
x, double
y);
double
Dev(double
x, double
y);
}
//Math类和MathProxy类分别实现IMath接口:
public
class
MathProxy : IMath
{
//
}
public
class
Math : IMath
{
//
}
此时我们在客户程序中就可以像使用Math类一样来使用MathProxy类了:
复制
保存
/// <summary>
/// Author : Terrylee
/// From : http://terrylee.cnblogs.com
/// </summary>
public
class
App
{
public
static
void
Main()
{
MathProxy proxy = new
MathProxy();
double
addresult = proxy.Add(2,3);
double
subresult = proxy.Sub(2,3);
double
mulresult = proxy.Mul(2,3);
double
devresult = proxy.Dev(2,3);
}
}
到这儿整个使用Proxy模式的过程就完成了,回顾前面我们的解决方案,无非是在客户程序和Math类之间加了一个间接层,这也是我们比较常见的
解决问题的手段之一。另外,对于程序中的接口Imath,并不是必须的,大多数情况下,我们为了保持对对象操作的透明性,并强制实现类实现代理类所要调用
的所有的方法,我们会让它们实现与同一个接口。但是我们说代理类它其实只是在一定程度上代表了原来的实现类,所以它们有时候也可以不实现于同一个接口。
效果及实现要点
Proxy模式根据种类不同,效果也不尽相同:
1.远程(Remote)代理:为一个位于不同的地址空间的对象提供一个局域代表对象。这个不同的地址空间可以是在本机器中,也可是在另一台机器
中。远程代理又叫做大使(Ambassador)。好处是系统可以将网络的细节隐藏起来,使得客户端不必考虑网络的存在。客户完全可以认为被代理的对象是
局域的而不是远程的,而代理对象承担了大部份的网络通讯工作。由于客户可能没有意识到会启动一个耗费时间的远程调用,因此客户没有必要的思想准备。
2.虚拟(Virtual)代理:根据需要创建一个资源消耗较大的对象,使得此对象只在需要时才会被真正创建。使用虚拟代理模式的好处就是代理对
象可以在必要的时候才将被代理的对象加载;代理可以对加载的过程加以必要的优化。当一个模块的加载十分耗费资源的情况下,虚拟代理的好处就非常明显。
3.Copy-on-Write代理:虚拟代理的一种。把复制(克隆)拖延到只有在客户端需要时,才真正采取行动。
4.保护(Protect or Access)代理:控制对一个对象的访问,如果需要,可以给不同的用户提供不同级别的使用权限。保护代理的好处是它可以在运行时间对用户的有关权限进行检查,然后在核实后决定将调用传递给被代理的对象。
5.Cache代理:为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果。
6.防火墙(Firewall)代理:保护目标,不让恶意用户接近。
7.同步化(Synchronization)代理:使几个用户能够同时使用一个对象而没有冲突。
8.智能引用(Smart Reference)代理:当一个对象被引用时,提供一些额外的操作,比如将对此对象调用的次数记录下来等。
总结
在软件系统中,增加一个中间层是我们解决问题的常见手法,这方面Proxy模式给了我们很好的实现。
参考资料
- Erich Gamma等,《设计模式:可复用面向对象软件的基础》,机械工业出版社
- Robert C.Martin,《敏捷软件开发:原则、模式与实践》,清华大学出版社
- 阎宏,《Java与模式》,电子工业出版社
- Alan Shalloway James R. Trott,《Design Patterns Explained》,中国电力出版社
- MSDN WebCast 《C#面向对象设计模式纵横谈(13):Proxy代理模式(结构型模式)》
分享到:
相关推荐
**设计模式之代理模式(Proxy Pattern)** 设计模式是软件工程中的一种最佳实践,它是在特定情境下解决常见问题的模板。代理模式是其中一种行为设计模式,它的核心思想是为一个对象提供一个替身或者代理,以控制对...
根据提供的标题“深入浅出设计模式之代理模式”与描述“将《Head First 设计模式》(中文版)按章节进行了分割,每章一个文件,方便大家下载”,我们可以推测出这部分内容主要聚焦于介绍和解释代理模式这一重要的设计...
代理模式是一种在软件设计中广泛使用的行为设计模式,它的核心思想是为...通过观看"设计模式之代理模式视频教学",你可以系统地学习代理模式的理论知识和实践技巧,提升自己的设计能力,更好地应对复杂的软件开发挑战。
大话设计模式之代理模式 经典代码 C#类
Java设计模式之代理模式 1.代理模式 1.1 静态代理 1.2 动态代理 1.3.代理模式使用原因和应用方面
代理模式是一种常用的设计模式,它在软件工程中扮演着重要的角色,特别是在.NET框架下。代理模式的核心思想是为一个对象提供一个替代品或代表,这个替代品能够控制对原对象的访问,使得客户端代码可以通过代理对象与...
### Java设计模式之虚拟代理模式详解 #### 一、引言 在软件工程领域,设计模式作为一种被广泛接受的最佳实践,对于提高代码质量和可维护性起着至关重要的作用。其中,“代理模式”作为结构型设计模式之一,在解决...
代理模式是一种常用的设计模式,它在软件开发中起到了中介或者代表的作用。代理模式的主要目的是为其他对象提供一种代理以控制对这个对象的访问。通过引入代理,我们可以增加新的功能,如缓存、日志记录、访问控制等...
代理模式是设计模式的一种,它提供了一种对目标对象进行增强或者控制访问的方式。在本实例中,我们将深入探讨Java中的代理模式及其应用。 代理模式的核心思想是为一个对象创建一个代理对象,这个代理对象在客户端和...
代理模式是面向对象设计模式中的一个关键概念,它在软件工程中扮演着重要角色,用于在客户端和目标对象之间创建一种代理关系,以提供额外的功能或控制。在代理模式中,代理类作为真实对象的代表,它可以在客户端与...
代理模式是设计模式中的一种结构型模式,它在对象交互中起到了中介的作用,允许通过代理对象来控制对原对象的访问。代理模式的核心思想是为一个对象提供一个替身,以便增加新的功能或者控制对原对象的访问。这种模式...
Java设计模式之代理模式[收集].pdf