设计模式- 代理模式
定义
为其他对象提供一种代理以控制对这个对象的访问。
理解
代理模式也是经常在我们生活中会发生的和编程中经常会接触到的事情。也许你没意识到这就是代理模式,但我想你应该接触过和使用过了。
1、比如你喜欢一个女孩子,你不敢直接表白,于是你找了一个朋友代你去表白,那个代你表白的朋友就相当于一个代理。
2、再从宏观一点的角度看,我们的操作系统也是一个代理模式,它是基于硬件和软件之间这么一个中间层、代理层。
3、如果你接触过三层架构,那我想你一定知道哪三层,模型层(Model)、数据访问层(DAL)、业务逻辑层(BLL)。其实业务逻辑层就是相当于一个代理层。
4、再比如生活中的这么一个例子,在大学校园里有些同学会做这么一个兼职工作,关于手机充值卡的代理商。其实宏观一点去思考,这也是代理模式的一种。
经过上面几点,代理模式其实也是有两点值得去注意的。第一点是实,第二点是虚。好比如第一个例子,想表白的同学他是实的,而代为表白的那个是虚的。三层架构也是一样,实际干活的数据访问层是实的,而业务逻辑层一层间接层他是虚的。
代理的应用
代理的应用其实也很广泛,以前我觉的三层里的BLL层可以去掉,但是对代理模式多了一些了解后,BLL层也是挺重要的。
我们来看一下代理模式的应用
1、远程代理:有使用过.NET里面的WebService的朋友可能会这种体会。我们在项目中添加引用了WebService后会生成一个WebReference文件夹,通过访问这个文件夹里面的文件,去访问实际上的方法。
2、缓存方面的代理:用户A想要打开一个网页,那么在没有代理层处理的情况下他是直接通过服务器打开网页。那么如果有一千个人在同一时间段那打开网页那么会给服务器造成很大的压力。这时候我们通过建立一个代理层,在这一层代理层上通过缓存的方式,来减少服务器的压力。
3、安全代理:例如做一个登陆的时候,我们可以对用户名、密码、IP地址、使用验证码等……在代理层对这些进行访问控制,实现访问的安全性。
Proxy模式的几个要点(在WEBCAST里抄下来的)
- “增加一层间接层”是软件系统中对许多复杂问题的一种常见解决方法。在面向对象系统中,直接使用某些对象会带来很多问题,作为间接层的proxy对象便是解决这一问题的常用手段。
- 具体proxy设计模式的实现方法、实现粒度都相差很大,有些可能对单个对象做细粒度的控制,如copy-on-write技术,有些可能对组件模块提供抽象代理层,在架构层次对对象做proxy。
- Proxy并不一定要求保持接口的一致性,只要能够实现间接控制,有时候损及一些透明性是可以接受的。
我是第一次听到copy-on-write,其实那里面讲的我不是很理解,但还是想把半懂半懂这一点记在这里:
这两句语句string A="Hello"; string B="Hello"; 虽然他们字符串都是相同的但是这种形式却开辟了两块内存空间。这会造成内存浪费。为了减少浪费,所以有了这种Copy-on-Write技术的提出。
例如StringBuilder就是一个典型的copy-on-write技术的使用:
这两句语句 StringBuilder A = new StringBuilder("Hello"); StringBuilder B = new StringBuilder("Heelo"); 他们能做到不造成内存浪费,原因是他们通过代理模式,由代理模式指向同一块内存空间。在想改变他们内容的时候,通过代理,把指向的内存空间复制一份,然后重写里面的内容,如果内容没有发生变化,就不改变。
UML图
简单的代码实现例子
/// <summary> /// 公共接口 /// </summary> interface ISubject { void Request(); } /// <summary> /// 被代理的类 /// </summary> public class RealSubject : ISubject { public void Request() { Console.WriteLine("被代理类的请求"); } } /// <summary> /// 代理类 /// </summary> public class Proxy : ISubject { RealSubject realSubject=new RealSubject(); public void Request() { realSubject.Request(); } } /// <summary> /// 客户代码 /// </summary> /// <param name="args"></param> static void Main(string[] args) { Proxy proxy = new Proxy(); proxy.Request(); }