Java设计模式之代理模式

本文详细介绍了代理模式的概念及其在Java中的应用。通过一个汽车行驶的例子,展示了如何使用代理模式为对象添加额外的功能,如记录行驶时间等。此外,还介绍了静态代理和动态代理的区别,并给出了动态代理的具体实现。
  代理模式:为其他对象提供一种代理,以控制对这个对象的访问,可以去掉某些功能,或者增加某些额外的服务.
  例如汽车具有行驶的功能,如果想为汽车再添加日志,记录行驶时间的工作时,便可以创建代理类进行其余的操作.

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

package com.proxy;

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

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

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>测试类

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

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

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

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

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方法中拦截原对象的调用,并通过反射机制来动态调用原对象的方法.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值