代理模式(java语言实现)

来源:互联网 发布:aes解密算法 编辑:程序博客网 时间:2024/04/30 10:07

概念和原理

代理模式的定义:

为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

组成:

抽象角色:通过接口或抽象类声明真实角色实现的业务方法。

代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。

真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。

优点

(1).职责清晰

真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件完成事务,附带的结果就是编程简洁清晰。

(2).代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了中介的作用和保护了目标对象的作用。

(3).高扩展性 模式结构

模式结构

一个是真正的你要访问的对象(目标类),一个是代理对象,真正对象与代理   对象实现同一个接口,先访问代理类再访问真正要访问的对象。

静态代理的定义和实现

静态代理定义: 代理对象和被代理对象在代理之前是确定的。 它们都实现相同的接口或者继承相同的抽象类。

代码实现:

UML:

这里写图片描述

Moveable.java

package com.imooc.proxy;public interface Moveable {    void move();}

Car.java

package com.imooc.proxy;import java.util.Random;public class Car implements Moveable {    @Override    public void move() {        //实现开车        try {            Thread.sleep(new Random().nextInt(1000));            System.out.println("moving....");        } catch (InterruptedException e) {            e.printStackTrace();        }    }}

CarTimeProxy.java

package com.imooc.proxy;public class CarTimeProxy implements Moveable {    private Moveable m;    public CarTimeProxy(Moveable m) {        super();        this.m = m;    }    @Override    public void move() {        long starttime = System.currentTimeMillis();        System.out.println("start moving....");        m.move();        long endtime = System.currentTimeMillis();        System.out.println("end moving....  Time consumed:"                + (endtime - starttime) + "ms !");    }}

CarLogProxy.java

package com.imooc.proxy;public class CarLogProxy implements Moveable {    private Moveable m;    public CarLogProxy(Moveable m) {        super();        this.m = m;    }    @Override    public void move() {        System.out.println("start logging....");        m.move();        System.out.println("end logging....");    }}

Client.java

package com.imooc.proxy;public class Client {    /**     * 测试类     */    public static void main(String[] args) {        Car car = new Car();        CarLogProxy clp = new CarLogProxy(car);        CarTimeProxy ctp = new CarTimeProxy(clp);        ctp.move();    }}

动态代理的实现

由于静态代理中的代理对象和被代理对象在代理之前是确定的。 所以,如果需要为不同的对象比如火车,自行车,的士 等不同的对象实现 时间代理就需要定义 TrainTimeProxy, BicycleTimeProxy, TexiTimeProxy…. 可以看到仅仅是为了实现不同类的 TimeProxy 我们就要新建那么多的类, 简直爆炸!!!

这个时候我们需要实现一种 TimeProxy 能为不同的类做代理。 这就用到了动态代理的知识。

代码实现:

TimeHandler.java

package com.imooc.jdkproxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class TimeHandler implements InvocationHandler {    private Object target;    public TimeHandler(Object target) {        super();        this.target = target;    }    /*     * 参数:     * proxied Object  被代理对象     * method  被代理对象的方法     * args 方法的参数     *     * 返回值:     * Object  方法的返回值     * */    @Override    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;    }}

Test.java

package com.imooc.jdkproxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Proxy;import com.imooc.proxy.Car;import com.imooc.proxy.Moveable;public class Test {    /**     * JDK动态代理测试类     */    public static void main(String[] args) {        Car car = new Car();        InvocationHandler h = new TimeHandler(car);        Class<?> cls = car.getClass();        /**         * loader  类加载器         * interfaces  实现接口         * h InvocationHandler         */        Moveable m = (Moveable)Proxy.newProxyInstance(cls.getClassLoader(),                                                cls.getInterfaces(), h);        m.move();    }}
0 0
原创粉丝点击