代理模式

来源:互联网 发布:大虫模型淘宝店 编辑:程序博客网 时间:2024/05/29 11:46

http://chjl2020.iteye.com/blog/517835



最近在看spring的源码,主要是IOC相关的。发现底层使用较多的代理模式、策略模式,还有Cglib库。有时间准备把他们全部弄清楚。先分析一下代理模式。

代理模式:给某一对象提供代理对象,并由代理对象控制具体对象的引用.

代理,指的就是一个角色代表另一个角色采取行动,就象生活中,一个红酒厂商,是不会直接把红酒零售客户的,都是通过代理来完成他的销售业务的.而客户,也不用为了喝红酒而到处找工厂,他只要找到厂商在当地的代理就行了,具体红酒工厂在那里,客户不用关心,代理会帮他处理.

代理模式涉及的角色:
1:抽象主题角色.声明了代理主题和真实主题的公共接口,使任何需要真实主题的地方都能用代理主题代替.

2:代理主题角色.含有真实主题的引用,从而可以在任何时候操作真实主题,代理主题功过提供和真实主题相同的接口,使它可以随时代替真实主题.代理主题通过持有真实主题的引用,不但可以控制真实主题的创建或删除,可以在真实主题被调用前进行拦截,或在调用后进行某些操作.

3:真实代理对象.定义了代理角色所代表的具体对象.

下面是代理模式的实现类图:


根据上图的关系,我们可以用客户买红酒来模拟代理模式的实现,

红酒代理商和红酒厂商都有销售红酒的只能,我们可以为他们定义一个共同的抽象主题角色。

package com.taobao.proxy;/** * 抽象主题角色,定义了真实角色和代理角色的公共接口 * @author mohe.jwj * */public interface SellInterface {public Object sell(); }

接着,我们定义真实主题角色(这里就是红酒工厂),它必须实现了SellInterface接口的


package com.taobao.proxy;/** * 真实主题角色,这里指红酒工厂角色,它实现了SellInterface接口  * @author mohe.jwj * */public class RedWineFactory implements SellInterface{      public Object sell(){          System.out.println("真实主题角色RedWineFactory 被调用了");          return new Object();      }  } 

下面是代理主题角色(这里指红酒代理商),同样,代理主题也必须实现SellInterface接口.

package com.taobao.proxy;/** * 代理主题角色,这里指红酒代理商.它除了也要实现了sellInterface接口外,还持有红酒  * 厂商RedWineFactory 对象的引用,从而使它能在调用真实主题前后做一些必要处理. * @author mohe.jwj * */public class RedWineProxy implements SellInterface { private RedWineFactory redWineFactory ;           public Object sell(){           if(checkUser()){//在通过代理主题角色,我们可以在真实主题角色被调用前做一些诸如权限判断的事情           System.out.println("具有权限调用对象!");         before();         Object obj = redWineFactory.sell();         after();             return obj ;           }else{               throw new RuntimeException();           }       }       public RedWineProxy(RedWineFactory redWineFactory){     this.redWineFactory = redWineFactory;     }     protected boolean checkUser(){              //do something              return true;       }     private void before(){     System.out.println("方法调用之前!");     }     private void after(){     System.out.println("方法调用之后!");     }}  

测试代码

package Test;import com.taobao.proxy.RedWineFactory;import com.taobao.proxy.RedWineProxy;import com.taobao.proxy.SellInterface;public class Test {/** * @param args */public static void main(String[] args) {// TODO Auto-generated method stubSellInterface sell = new RedWineProxy(new RedWineFactory());      sell.sell();  }}

运行结果:

具有权限调用对象!
方法调用之前!
真实主题角色RedWineFactory 被调用了
方法调用之后!


其实上面的before()方法、after()方法就是模拟拦截的概念。拦截机制是代理模式的重要使用方式之一,除了拦截,代理模式还常用于资源加载,当我们要加载的资源很大时,我们可以让真实主题角色在后台加载资源,让代理主题角色负责处理前台的等待提示信息.还有就是授权机制,通过代理能拦截真实主题的能力,来控制真实主题的访问权限。