java设计模式(四)代理模式

  适用于为不同操作添加共同的额外行为。通过代理对象访问目标对象,这样可以增加对目标对象的额外操作,达到扩展目标对象功能的目的,如spring事务、AOP等。

  要点:1)抽象角色:通过接口或抽象类声明真实角色实现的业务方法。(例子中的Move)

     2)代理角色:实现抽象角色,是真实角色的代理(例子中的*Proxy)

     3)真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。(例子中的MoveImpl)

一、静态代理

1、继承实现静态代理

移动接口

public interface Move {
    public void move();
}

移动实现类

public class MoveProxy implements Move {
    public void move() {
        System.out.println("汽车正在运行......");
    }
}

车代理类

public class CarProxy extends MoveImpl {
    @Override
    public void move() {
        long start_time = new Date().getTime();
        System.out.println("汽车开始运行......");
        super.move();
        long end_time = new Date().getTime();
        System.out.println("汽车结束运行,运行时间:" + (end_time - start_time));
    }
}

测试

public class Model {
    public static void main(String[] args) {
        CarProxy carProxy = new CarProxy();
        carProxy.move();
    }
}

2、聚合实现静态代理

  推荐使用聚合实现动态代理,这样可以方便实现多个代理顺序交换,方便扩展,如下

移动接口

public interface Move {
    public void move();
}

移动实现类

public class MoveProxy implements Move {
    public void move() {
        System.out.println("汽车正在运行......");
    }
}

车代理类

public class CarProxy extends MoveImpl {
    @Override
    public void move() {
        long start_time = new Date().getTime();
        System.out.println("汽车开始运行......");
        super.move();
        long end_time = new Date().getTime();
        System.out.println("汽车结束运行,运行时间:" + (end_time - start_time));
    }
}

日志代理

public class LogProxy implements Move {

    private Move obj;

    public LogProxy(Move obj) {
        this.obj = obj;
    }

    public void move() {
        System.out.println("日志开始......");
        obj.move();
        System.out.println("日志结束......");
    }
}

测试

public class Model {
    public static void main(String[] args) {
        //推荐使用聚合实现动态代理,这样可以方便实现多个代理顺序交换,方便扩展,如下
        MoveImpl moveProxy = new MoveImpl();
        CarPropxy carPropxy = new CarPropxy(moveProxy);
        LogProxy logProxy = new LogProxy(carPropxy);
        logProxy.move();

        System.out.println();
        MoveImpl moveProxy1 = new MoveImpl();
        CarPropxy carPropxy1 = new CarPropxy(moveProxy1);
        LogProxy logProxy1 = new LogProxy(carPropxy1);
        logProxy1.move();
    }
}

二、动态代理

移动接口

public interface Move {
    public void move();
}

移动实现类

public class MoveProxy implements Move {
    public void move() {
        System.out.println("汽车正在运行......");
    }
}

 日志代理

public class LogHandler implements InvocationHandler {

    private Object obj;

    public LogHandler(Object obj) {
        this.obj = obj;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("日志开始......");
        method.invoke(obj);
        System.out.println("日志结束.......");
        return null;
    }
}

时间代理

public class TimeHandler implements InvocationHandler {

    private Object obj;

    public TimeHandler(Object obj) {
        this.obj = obj;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        long start_time = new Date().getTime();
        System.out.println("汽车开始运行......");
        method.invoke(obj);
        long end_time = new Date().getTime();
        System.out.println("汽车结束运行,运行时间:" + (end_time - start_time));
        return null;
    }
}

测试

public class Model {
    public static void main(String[] args) {
        MoveImpl move = new MoveImpl();
        Class c = move.getClass();

        TimeHandler t = new TimeHandler(move);
        Move m = (Move) Proxy.newProxyInstance(c.getClassLoader(), c.getInterfaces(), t);
        LogHandler l = new LogHandler(m);
        Move m1 = (Move) Proxy.newProxyInstance(c.getClassLoader(), c.getInterfaces(), l);
        m1.move();
    }
}

二者区别:JAVA学习篇--静态代理VS动态代理

 代码:https://github.com/shaoyesun/jdk_test.git

posted @ 2017-07-19 00:15  code.world  Views(222)  Comments(0Edit  收藏  举报