代理模式 java代码小示例
 

2008-12-29 作者:moucahe 来源:javaeye.com

 

1、定义及作用

代理模式给某一对象提供一个代理对象,并由代理对象来控制对原对象的使用。通过该模式可以控制客户端和目标对象间的作用关系。     

2、涉及角色

抽象角色:真实对象和代理对象的共同接口。

代理角色:实现了抽象角色以代替客户端中的真实角色。在代理角色内部含有对真实角色的引用,在执行真实角色的动作时执行额外的动作。

真实角色:客户端实际引用的对象,也即代理角色代理的对象。

3、简单实现

抽象角色java 代码

  1. package proxy;   
  2. /**  
  3.  *   
  4.  * @author mouca.he  
  5.  *  
  6.  */  
  7. public interface AbstractSubject {   
  8.     /**  
  9.      * 客户请求操作  
  10.      *  
  11.      */  
  12.     public void say();   
  13.   
  14. }   

真实角色java 代码

  1. package proxy;   
  2. /**  
  3.  *   
  4.  * @author mouca.he  
  5.  *  
  6.  */  
  7. public class RealSubject implements AbstractSubject{   
  8.   
  9.     public void say() {   
  10.         // TODO 自动生成方法存根   
  11.         System.out.println("RealSubject.say():"+"这是真实角色方法!");   
  12.     }   
  13.        
  14. }  

代理角色java 代码

  1. package proxy;   
  2.   
  3. /**  
  4.  *   
  5.  * @author mouca.he  
  6.  *   
  7.  */  
  8. public class ProxySubject implements AbstractSubject {   
  9.   
  10.     private RealSubject realSubject;// 真实角色的引用   
  11.   
  12.     public ProxySubject() {   
  13.     }   
  14.   
  15.     public ProxySubject(RealSubject realSubject) {   
  16.         this.realSubject = realSubject;   
  17.     }   
  18.   
  19.     private void preRequest() {   
  20.         System.out.println("请求前预处理:ProxySubject.preRequest()");   
  21.     }   
  22.   
  23.     private void afterRequest() {   
  24.         System.out.println("请求处理完毕后动作:ProxySubject.afterRequest()");   
  25.     }   
  26.   
  27.     public void say() {   
  28.         // TODO 自动生成方法存根   
  29.         preRequest();   
  30.   
  31.         if (realSubject == null) {   
  32.             realSubject = new RealSubject();   
  33.         }   
  34.         realSubject.say();   
  35.   
  36.         afterRequest();   
  37.   
  38.     }   
  39.   
  40. }   

客户端java 代码

  1. package proxy;   
  2. /**  
  3.  *   
  4.  * @author mouca.he  
  5.  *  
  6.  */  
  7. public class TestProxy {   
  8.   
  9.     /**  
  10.      * @param args  
  11.      */  
  12.     public static void main(String[] args) {   
  13.         // TODO 自动生成方法存根   
  14.         AbstractSubject abstractSubject = new ProxySubject();//代理对象   
  15.            
  16.         abstractSubject.say();   
  17.         /*  
  18.          * 控制台输出:  
  19.          * 请求前预处理:ProxySubject.preRequest()  
  20.          * RealSubject.say():这是真实角色方法!  
  21.          * 请求处理完毕后动作:ProxySubject.afterRequest()  
  22.          */  
  23.   
  24.     }   
  25.   
  26. }  

4、java动态代理

顾名思义,在运行时java动态生成代理类。给定一组代理的接口,通过java动态代理机制将动态生成含有这些接口的代理类。涉及到接口java.lang.reflect.InvocationHandler和类java.lang.reflect.Proxy。所有代理类模板都必须实现接口InvocationHandler,通过Proxy的静态方法newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h)来动态生成代理类实例。

动态代理java 代码

  1. package proxy;   
  2.   
  3. import java.lang.reflect.InvocationHandler;   
  4. import java.lang.reflect.Method;   
  5. import java.lang.reflect.Proxy;   
  6. /**  
  7.  *   
  8.  * @author mouca.he  
  9.  *  
  10.  */  
  11. public class JavaDynamicProxy implements InvocationHandler{   
  12.   
  13.     private Object prObject;   
  14.        
  15.     public JavaDynamicProxy(Object prObject){   
  16.         this.prObject = prObject;   
  17.     }   
  18.     /**  
  19.      * 动态代理类工厂方法  
  20.      * @param object  
  21.      * @return  
  22.      */  
  23.     public static Object factory(Object object){   
  24.         Class cls = object.getClass();   
  25.         //生成动态代理类实例   
  26.         return Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), new JavaDynamicProxy(object));   
  27.     }   
  28.     /**  
  29.      * @param args  
  30.      */  
  31.     public static void main(String[] args) {   
  32.         // TODO 自动生成方法存根   
  33.   
  34.         AbstractSubject abstractSubject = (AbstractSubject)factory(new RealSubject());//代理对象   
  35.            
  36.         abstractSubject.say();   
  37.         /*  
  38.          * 控制台输出:  
  39.          * 请求前预处理:ProxySubject.preRequest()  
  40.          * RealSubject.say():这是真实角色方法!  
  41.          * 请求处理完毕后动作:ProxySubject.afterRequest()  
  42.          */  
  43.   
  44.     }   
  45.   
  46.     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {   
  47.         // TODO 自动生成方法存根   
  48.         System.out.println("调用真实对象之前。。。。。");   
  49.   
  50.         method.invoke(prObject, args);//调用真实对象的代理方法   
  51.            
  52.         System.out.println("调用真实对象之前。。。。。");   
  53.         return null;   
  54.     }   
  55.   
  56. }   

火龙果软件/UML软件工程组织致力于提高您的软件工程实践能力,我们不断地吸取业界的宝贵经验,向您提供经过数百家企业验证的有效的工程技术实践经验,同时关注最新的理论进展,帮助您“领跑您所在行业的软件世界”。
资源网站: UML软件工程组织