设计模式培训之五:代理模式
查看本人文章索引请通过http://www.cnblogs.com/seesea125/archive/2012/04/17/2453256.html
一、 什么是代理模式?
代理模式,为其他对象提供一种代理以控制对这个对像的访问。
代理模式结构图:
1. 远程代理,也就是为一个对象在不同的地址空间提供局部代表。这样可以隐藏一个对象存在不两只的地址空间的事实。(他所使用到的例子。Webservice在.net 中的应用,当我应用程序的项目中加入一个Web引用,引用一个WebService,此时会在项目中生成一个Webreference的文件夹和一些文件,其实它们就是代理,这就使得客户端程序调用代理就可以解决远程访问的问题。)
2. 虚拟代理,是根据需要创建开销很大的对象。通过它来存放实例化需要很长时间的真实对象。(例子,比如说你打一个很大的Html网页时,里面可能有很多的文字和图片,但你还是可以很快打开它,些时你所看到的是所有文字,但图片却是一张一张地下载后才能看到。那些未打开的图片框,就是通过虚拟代理来替代了真实的图片,此时代理存储了真实图片的路径和尺寸。)
3. 安全代理,用来控件真实对象访问时的权限。(例子 不同的访问权限的时候。)
4. 智能指引,是指当调用真实的对象时,代理处理另外一些事。(例子:如计算真实对旬的引用次数,这样当该对象没有引用时,可以自动释放它ak当第一次引用一个持久对象时,将它装入内存或在访问一个实际对象前,检查是否已经锁定它,以确保其他对象不能改变它。它们都是通过代理在访问一个对象时附加一些内务处理。)
三、 下面写一段实现代理模式的代码.
经过上面的实战,我们来思考一下
abstract class subject { public abstract void Request(); } class RealSubject:subject { public override void Request() Console.WriteLine("真实的追求者."); } class Proxy:subject { RealSubject realsubject; public override void Request() { if (realsubject == null) { realsubject = new RealSubject(); } realsubject.Request(); } } class Program { static void Main(string[] args) { Proxy pr = new Proxy(); pr.Request(); Console.Read(); } }
四、疑问解答:
1. 为什么用代理模式?
答:客户端无法直接操作实际对象。么为什么无法直接操作?一种情况是你需要调用的对象在另外一台机器上,你需要跨越网络才能 访问,如果让你直接coding去调用,你需要处理网络连接、处理打包、解包等等非常复杂的步骤,所以为了简化客户端的处理,我们使用代理模式,在客户端 建立一个远程对象的代理,客户端就象调用本地对象一样调用该代理,再由代理去跟实际对象联系,对于客户端来说可能根本没有感觉到调用的东西在网络另外一 端,这实际上就是Web Service的工作原理。另一种情况虽然你所要调用的对象就在本地,但是由于调用非常耗时,你怕影响你正常的操作,所以特意找个代理来处理这种耗时情 况,一个最容易理解的就是Word里面装了很大一张图片,在word被打开的时候我们肯定要加载里面的内容一起打开,但是如果等加载完这个大图片再打开 Word用户等得可能早已经跳脚了,所以我们可以为这个图片设置一个代理,让代理慢慢打开这个图片而不影响Word本来的打开的功能。
2. 为什么要抽象这个接口呢?
答:其实抽象接口有一个最大的原因就是约束双方的行为!什么意思呢?其实就是我逼迫Proxy 必须实现某些方法,而这些方法恰恰是对外公开的主要业务方法。当然也可以靠程序员自律,但是多一个约束总归是好的,至少如果没有实现指定方法我们可以在编 译期就发现错误,总比执行时才能发现错误要好。另外的原因可能都得归结到使用接口的好处上去了,这里不再赘述,自己去查接口的文章介绍了。
3. 如查实现权限验证,为何要对该类添加一个代理类?而不是在此类里面直接加上权限判断呢?
答:在程序设计中有一个类的单一性原则问题,这个原则很简单,就是每个类的功能尽可能单一。为 什么要单一,因为只有功能单一这个类被改动的可能性才会最小,就拿刚才的例子来说,如果你将权限判断放在当前类里面,当前这个类就既要负责自己本身业务逻 辑、又要负责权限判断,那么就有两个导致该类变化的原因,现在如果权限规则一旦变化,这个类就必需得改,显然这不是一个好的设计。