代理模式

2018-08-13  本文已影响0人  jiting45

https://www.jianshu.com/p/cbd58642fc08
代理模式分为静态代理和动态代理。
静态代理:
1、作用:通过代理对象间接访问目标对象。
2、解决的问题:(1)、不想直接访问目标对象
(2)、无法直接访问目标对象
3、三个角色:(1)、抽象对象接口;(2)、真实对象(委托类、被代理对象); (3)、代理对象(内部含有真实对象的引用)
4、Demo:

public interface Sell {
    void sell();
}
public class Sellor implements Sell {
    @Override
    public void sell() {
        Log.d("TAG","十元一个");
    }
}
public class Agent implements Sell {
    private Sellor sellor;
    private int sellNum;

    public Agent(Sellor sellor) {
        this.sellor = sellor;
    }

    @Override
    public void sell() {
        if (sellNum > 1000) {// 如果卖出1000个后,再按照10元1个的单价卖
            sellor.sell();
        }
    }
}

这样就可以只改变代理类就能够控制想要的结果了,而不需要每次都改动真实类。

动态代理:和静态代理相比,动态代理是在程序运行时创建的代理方式。相比于静态代理,动态代理的优势在于可以很方便的对代理类的函数进行统一的处理,而不用修改每个代理类的函数。
1、解决的问题:统一的处理代理类的函数,而不是修改每一个代理类。
2、四个角色:(1)、抽象的对象接口;(1)、抽象对象接口;(2)、真实对象(委 托类、被代理对象); (3)、代理对象;(4)、中介对象(实现InvocationHandler)
3、API:
InvocationHandler

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

当我们调用代理类对象的方法时,这个“调用”会转送到invoke方法中,代理类对象作为proxy参数传入,参数method标识了我们具体调用的是代理类的哪个方法,args为这个方法的参数。这样一来,我们对代理类中的所有方法的调用都会变为对invoke的调用,这样我们可以在invoke方法中添加统一的处理逻辑(也可以根据method参数对不同的代理类方法做不同的处理)。
newProxyInstance

public static Object newProxyInstance(ClassLoader loader, 
    Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException

方法的三个参数含义分别如下:
loader:定义了代理类的ClassLoder;
interfaces:代理类实现的接口列表
h:调用处理器,也就是实现了InvocationHandler接口的类实例

4、Demo:

public interface Sell { void sell(); void ad();}
public class Vendor implements Sell { 
  public void sell() { 
    System.out.println("In sell method"); 
  } 
  public void ad() { 
    System.out.println("In ad method") 
  }
}
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;
  }
}
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)); 
  sell.sell(); 
  sell.ad(); 
  }
}
上一篇 下一篇

猜你喜欢

热点阅读