论坛首页 Java版 设计模式

代理模式(Proxy)

浏览 338 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
时间:2008-05-09
代理模式,个人认为就是把你要使用的一个对象尽享封装,包装。编程原对象的一个副本,在使用的时候直接使用他这个副本就可以了!他的作用用专业点的语言描述就是为其他的对象提供一个代理方便控制这个对象。当我们不能直接调用另外一个对象,但是又不得不用这个对象的某些功能,此时代理对象就能起到链接客户和目标对象的一个代理.
代理模式一般涉及到三个角色,分别为:
1. 抽象角色:他提供真实对象和代理对象的共同接口。
2. 代理角色:通俗地说,代理角色是对原对象(目标对象)进行包装,他有着和原对象相同的接口,并且可以执行真实对象的操作。
3. 真实角色:即目标对象,最终我们需要对他的操作。
代理模式分为两种,一 静态代理,二 动态代理。

接下来我们介绍一下两种代理模式:

一 静态代理
静态代理即 代理对象和被代理对象在代理之前已经确定好了。他们一起实现相同的接口或者是继承相同的抽象类。例如:
//定义抽象角色
public abstract class AbsRole{
  abstract public void work();
}


//定义真实角色
public class RealRole extends AbsRole{
  public RealRole(){ }

  public void work(){
    System.out.println("调用真实角色中函数!");
  }
}

//代理角色
public class ProxyRole extends AbsRole{
  public RealRole real ;
  
  public ProxyRole(){
  }

  public void work(){
    this.beforeMethod();
    if(real == null){
      real = new RealRole();
    }
    real.work();
    this.endMethod();
  }

  public void beforeMethod(){
    System.out.println("代理前执行函数->beforeMethod()");
  }
  
  public void endMethod(){
    System.out.println("代理时候后执行函数->endMethod()");
  }
}


各种角色我们都已经定义好了,我们开始测试一下。

public class Main(){
  public static void main(String[] args){
    AbsRole ar = new ProxyRole();
    ar.work();
  }
}


二 动态代理
顾名思义,就是不知道到底那个类需要做代理,在使用的时候,更具情况临时决定。
java动态代理主要是使用java.lang.reflect包中的两个类。
1. interface InvocationHandler: 他中定义了一个方法
  public Object invoke(Object obj,Method method,Object[] obs)

其中第一个参数 obj 指的是代理类,method是被代理的方法,obs是指被代理的方法的参数组。此方法由代理类来实现。
2. Proxy:该类为动态代理类,主要包括以下内容:

  protected Proxy(InvocationHandler h);

  static Class getProxyClass(ClassLoader loader,Class[] interfaces);

  static Object newProxyInstance(ClassLoader loader,Class[]interfaces,InvocationHandler h);


动态代理其实是在运行时生成class,所以,我们必须提供一组interface,然后告诉他class已经实现了这些interface,而且在生成Proxy的时候,必须给他提供一个handler,让他来接管实际的工作。
现在我们把静态代理的例子修改一下:
//定义抽象角色;
public interface AbsRole{
  public void work();
}


接下来定义真实角色;
public class RealRole implements AbsRole{
  public RealRole(){};
  
  public void work(){
    System.out.println("调用真实角色方法:RealRole.work()");
  }
}

然后书写动态代理编码
public class DynamicProxyRole implements InvocationHandler{
  private Object sub;
  
  public DynamicProxyRole(){}

  public DynamicProxyRole(Object ob){
    this.sub = ob;
  }

  public Object invoke(Object proxy, Method method, Object[] obs) throws Throwable{
    method.invke(sub,obs);
    return null;
  }
}

代理类已经书写完毕,看看是否能正常运行。
public class Main{
  public static void main(String[] args){
    RealRole  rr  = new RealRole();
    InvocationHandler dynamicProxy = new DynamicProxyRole(rr);
    Class<?> cls = rs.getClass();
    
    AbsRole r = (AbsRole)Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),DynamicProxyRole);
    r.work();
  }
}



调试成功,动态代理功能完成。

通过静态代理和动态代理学习,我们小结一下:
静态代理需要事先确定代理对象和被代理对象,他们要一起继承或者是实现相同的抽象类。动态代理可以在使用的时候传入真实对象,得到代理。动态代理还是主要依靠java本身的语言特性,实现代理,更加方便
   
时间:2008-05-13
从上面的例子,没看出代理的真实用途
   
0 请登录后投票
时间:2008-05-13
估计又要被评新手帖了
   
0 请登录后投票
时间:昨天
我认为写的还是不错的。

要理解Spring的AOP,必须要先理解什么是动态代理。

个人认为Spring的AOP是建立在IOC基础之上的动态代理模式。

请各位大人批评指正,小弟是新手。

PS:貌似Spring的AOP很少应用到
   
0 请登录后投票
论坛首页 Java版 设计模式

跳转论坛:
JavaEye推荐
    快速回复 引用上一条消息 (Alt+S)