设计模式-代理模式

1、简述

代理模式中可以映射为现实生活中的生产者、中介商、消费者,生产者可抽象为委托类,中介商可抽象为代理类,消费者可以抽象为调用者对象。代理模式可以简化消费者购买商品的模式,比如超市里面可以购买各种商品,消费者只需要找到超市和超市里面商品即可,不需跑到各个生产商品的工厂。

优点一:可以隐藏委托类的实现;
优点二:可以实现客户与委托类间的解耦,在不修改委托类代码的情况下能够做一些额外的处理。

2、静态代理类

若代理类在程序运行前就已经存在,那么这种代理方式被成为 静态代理 ,这种情况下的代理类通常都是我们在Java代码中定义的。 通常情况下, 静态代理中的代理类和委托类会实现同一接口或是派生自相同的父类。

3、动态代理

(1)InvocationHandler接口
在使用动态代理时,我们需要定义一个位于代理类与委托类之间的中介类,这个中介类被要求实现InvocationHandler接口,这个接口的定义如下:

public interface InvocationHandler {
 Object invoke(Object proxy, Method method, Object[] args); 
  }

(2)委托类的定义
动态代理方式下,要求委托类必须实现某个接口,这里我们实现的是Sell接口。委托类Vendor类的定义如下:

public class Vendor implements Sell {
  public void sell() {
  System.out.println("In sell method"); 
  }
  
public void ad() {
  System,out.println("ad method")
  }
    } 

(3)中介类
上面我们提到过,中介类必须实现InvocationHandler接口,作为调用处理器”拦截“对代理类方法的调用。中介类的定义如下:

public class DynamicProxy implements InvocationHandler {
  private Object obj; //obj为委托类对象;
  public DynamicProxy(Object obj) {
  this.obj = obj;
  }
 
  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 
  System.out.println("before");
  Object result = method.invoke(obj, args);
  System.out.println("after");
  return result;
  }
      
(4)动态生成代理类
public class Main {
  public static void main(String[] args) {
  //创建中介类实例
  DynamicProxy inter = new DynamicProxy(new Vendor());
  //加上这句将会产生一个$Proxy0.class文件,这个文件即为动态生成的代理类文件
  System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
  //获取代理类实例sell
  Sell sell = (Sell)(Proxy.newProxyInstance(Sell.class.getClassLoader(), new Class[] {Sell.class}, inter)); 
  //通过代理类对象调用代理类方法,实际上会转到invoke方法调用
  sell.sell();
  sell.ad();
  }
(5)运行结果
before
In sell method
after
before
In ad method
after
 

 

posted @ 2017-11-22 11:38  快乐的追求  阅读(204)  评论(0编辑  收藏  举报