设计模式--代理模式

时间:2017-01-20 08:59:14   收藏:0   阅读:207

代理模式(Proxy Pattern)

定义:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。

类型:结构型模式

类图:

技术分享

由上图代理模式的结构为:

根据代理类的生成时间不同可以将代理分为静态代理动态代理两种。

静态代理

由程序员创建或工具生成代理类的源码,再编译代理类。所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了

代码示例:

1.抽象角色

public interface AbstractSubject {
     void doSomething();
}   

2.代理角色

public class ProxySubject implements AbstractSubject{
    private AbstractSubject  real ;
    public ProxySubject(AbstractSubject  real) {
         this.real=real ;
    }
    @Override
    public void doSomething() {
         real.doSomething();
    }
    public void doOtherthing() {
    }
}   

3.真实角色

public class RealSubject implements AbstractSubject{
     @Override
     public void doSomething() {
        System.out.println( "真实角色被使用" );
    }
}   

4.客户端

public class Client {
     public static void main(String[]  args ) {
        RealSubject real = new  RealSubject();
        ProxySubject proxy = new  ProxySubject( real );
         proxy.doSomething();
    }
}  

5.静态代理的优缺点

优点: 业务类只需要关注业务逻辑本身,保证了业务类的重用性。这是代理的共有优点。 
缺点:

动态代理

动态代理类的源码是程序在运行期间由JVM根据反射等机制动态生成的,所以不存在代理类的字节码文件。代理角色和真实角色的联系在程序运行时确定。 
1.首先看看和动态代理相关JavaAPI 

要了解 Java 动态代理的机制,首先需要了解以下相关的类或接口:

2.动态代理实现步骤

  具体有如下四步骤:

  1. 通过实现 InvocationHandler 接口创建自己的调用处理器;
  2. 通过为 Proxy 类指定 ClassLoader 对象和一组 interface 来创建动态代理类;
  3. 通过反射机制获得动态代理类的构造函数,其唯一参数类型是调用处理器接口类型;
  4. 通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入。

示例代码

1.抽象角色和真实角色代码与上述相同 。 
2. 创建自己的调用处理器:

public class SubjectHandler implements InvocationHandler{
    AbstractSubject real;
    public SubjectHandler(AbstractSubject real){
        this.real=real;
    }
    @Override
    public Object invoke(Object obj, Method method, Object[] args)throws Throwable {
        System.out.println("代理类预处理任务");
        //利用反射机制将请求分派给委托类处理。Method的invoke返回Object对象作为方法执行结果。  
  //因为示例程序没有返回值,所以这里忽略了返回值处理
        method.invoke(real, args);
        System.out.println("代理类后续处理任务");
        return null;
    }
}

3.客户端 :

public class Client {
    public static void main(String[] args) {
        RealSubject real=new RealSubject();
        SubjectHandler handler=new SubjectHandler(real);
        //生成代理类对象
        AbstractSubject proxy=(AbstractSubject) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{AbstractSubject.class},handler);
        proxy.doSomething();
    }
}

4.动态代理的优缺点

优点: 
  动态代理与静态代理相比较,最大的好处是接口中声明的所有方法都被转移到调用处理器一个集中的方法中处理(InvocationHandler.invoke)。这样,在接口方法数量比较多的时候,我们可以进行灵活处理,而不需要像静态代理那样每一个方法进行中转。

缺点: 
  诚然,Proxy 已经设计得非常优美,但是还是有一点点小小的遗憾之处,那就是它始终无法摆脱仅支持 interface 代理的桎梏,因为它的设计注定了这个遗憾。回想一下那些动态生成的代理类的继承关系图,它们已经注定有一个共同的父类叫 Proxy。Java 的继承机制注定了这些动态代理类们无法实现对 class 的动态代理,原因是多继承在 Java 中本质上就行不通。

原文:http://www.cnblogs.com/Avaoder/p/6321808.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!