设计模式之Proxy(代理)
转自:
http://www.blogjava.net/lusm/archive/2007/08/08/135355.html
http://www.blogjava.net/lusm/archive/2007/08/09/135433.html
设计模式中定义 : Fronting for another object(为其他对象提供一种代理以控制对这个对象的访问).
为什么要使用Proxy?
1.授权机制 不同级别的用户对同一对象拥有不同的访问权利,如Jive论坛系统中,就使用Proxy进行授权机制控制,访问论坛有两种人:注册用户和游客(未注册用 户),Jive中就通过类似ForumProxy这样的代理来控制这两种用户对论坛的访问权限.
2.某个客户端不能直接操作到某个对象,但又必须和那个对象有所互动.
举例两个具体情况:
(1)如果那个对象是一个是很大的图片,需要花费很长时间才能显示出来,那么当这个图片包含在文档中时,使用编辑器或浏览器打开这个文档,打开文档必须很 迅速,不能等待大图片处理完成,这时需要做个图片Proxy来代替真正的图片.
(2)如果那个对象在Internet的某个远端服务器上,直接操作这个对象因为网络速度原因可能比较慢,那我们可以先用Proxy来代替那个对象.
总之原则是,对于开销很大的对象,只有在使用它时才创建,这个原则可以为我们节省很多宝贵的Java内存. 所以,有些人认为Java耗费资源内存,我以为这和程序编制思路也有一定的关系.
其他需要使用proxy的情况这里不一一列举,大家在实践的时候再慢慢体会。
如何使用Proxy?
proxy主要分为静态代理模式和动态代理模式。
静态代理模式 :
一个简单的例子:
运行结果:
before method invoking
我想买一台三星电脑三星公司产品
after method invoking
before method invoking
我想买一台联想电脑联想公司产品
after method invoking
在上例中,Lenovo.java和SamSung.java是真正实现buy方法的类,ComputerProxy为代理类,Computer为他们共同的基类。
ComputerProxy里面并没有创建新的方法,它根据传入对象的类型(Lenovo或者SamSung)来决定到底是用Lenovo里面的buy方法,还是SamSung里面的buy方法,它充当的是Lenovo和SamSung的前台,也由此对应了代理模式的定义:Fronting for another object 。
动态代理模式:
前面一个文章里的代码很简单(只是让大家了解什么是代理),实现的是静态代理,做为电脑代理商的ComputerProxy,在电脑行业 为电脑生产商(三星,联想)和客户提供服务,提供各种方便。
郁闷的是,如果我现在增加一个行业,比如下面要讲到的Car汽车行业,那么,我们只能增加一个代理了,也就是说我们要再写一个CarProxy代码,我们现在假设我们有很多个行业,那么,无疑我们的工作量开始大了,有没有什么办法让我们的代理商实现跨行业代理 呢?
答案是:可以。这就是我们这里讲的动态代理产生存在的意义了。
如果你要增加一个汽车行业,则会增加以下代码:
如果有很多行业的话,代理类(上面例子中的CarProxy)也会很多,工作量变大的同时,也带来了可维护性的问题。如果用动态代理的话,可以很方便的解决这个问题。
下面我们在上面静态代理模式例子的基础上,增加一个汽车行业。
完整的代码如下:
动态代理类:
运行结果:
before method invoking
SamSung三星公司产品
after method invoking
before method invoking
Lenovo联想公司产品
after method invoking
before method invoking
RollsRoyce劳斯莱斯公司产品
after method invoking
动态代理模式中,只需要一个代理类(AllProxy)就完成了所有的代理工作,减少代码。