您的位置:首页 > 编程语言 > Java开发

Java设计模式之代理模式

2015-09-07 14:05 357 查看
[code]  代理模式:为其他对象提供一种代理,以控制对这个对象的访问,可以去掉某些功能,或者增加某些额外的服务.
  例如汽车具有行驶的功能,如果想为汽车再添加日志,记录行驶时间的工作时,便可以创建代理类进行其余的操作.


1>创建一个interface包含汽车的move()方法

[code]package com.proxy;

/**
 * Created by panlu on 15-9-5.
 */
public interface Moveable {
    void move();
}


2>真实的类(Car)和代理类(ProxyCar02)都需要实现这个接口

[code]package com.proxy;

/**
 * Created by panlu on 15-9-5.
 */
//使用集合的方式进行代理模式
public class ProxyCar02 implements Moveable {
    private Car car01;

    public ProxyCar02(Car car01) {
        super();
        this.car01 = car01;
    }

    @Override
    public void move(){
        long startTime = System.currentTimeMillis();
        System.out.println("汽车开始行驶...");

        car01.move();

        long endTime = System.currentTimeMillis();
        System.out.println("汽车停止行驶... "+(endTime-startTime));
    }
}


3>测试类

[code]package com.proxy;

/**
 * Created by panlu on 15-9-5.
 */
public class ClientTest {
    public static void main(String[] args) {
        //使用集合方式
        Car c = new Car();
        Moveable m1 = new ProxyCar02(c);
        m1.move();
    }
}


[code]  从上面的例子可以看出代理模式的工作方式,首先,因为ProxyCar02和Car都实现了共同的接口,这使我们可以在不改变原来接口的情况下,只要用Car对象的地方,都可以用ProxyCar02来代替.其在客户和真实,ProxyCar02在Client和Car之间起了一个中介作用,利用这个中介平台,我们可以在把客户请求传递给Car之前,做一些必要的预处理.


Java对代理模式的支持—–动态代理

[code]   上面的代理,我们强迫代理类ProxyCar02实现了抽象接口Moveable.这导致我们的代理类无法通用于其他接口,所以不得不为每一个接口实现一个代理类.幸好,java为代理模式提供了支持. 
   java主要是通过Proxy类和InvocationHandler接口来给实现对代理模式的支持的.


下面用java的代理机制来实现上面的例子

[code]package com.jdkproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * Created by panlu on 15-9-5.
 */
//事务处理器
public class TimeHandler implements InvocationHandler {

    private Object target;

    public TimeHandler(Object target) {
        super();
        this.target = target;
    }

    @Override
    //在该方法中添加具体的业务逻辑
    /*
    *   proxy:  指代我们所代理的那个真实对象
    *   method: 指代的是我们所要调用真实对象的某个方法的Method对象
    *   args:  指代的是调用真实对象某个方法时接受的参数
    * */
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        long startTime = System.currentTimeMillis();
        System.out.println("汽车开始行驶...");

        method.invoke(target);

        long endTime = System.currentTimeMillis();
        System.out.println("汽车停止行驶... "+(endTime-startTime));
        return null;
    }
}


通过上面的代码可以看出,代理类TimeHandler 并没有实现我们定义的Moveable接口,

而是实现了java的InvocationHandler接口,这样就把代理汽车角色和我们的业务代码分离开来,使代理对象能通用于其他接口.

其实InvocationHandler接口就是一种拦截机制,当系统中有了代理对象以后,对原对象(真实汽车)方法的调用,都会转由InvocationHandler接口来处理,并把方法信息以参数的形式传递给invoke方法,这样,我们就可以在invoke方法中拦截原对象的调用,并通过反射机制来动态调用原对象的方法.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: