设计模式之动态代理模式(一)

问题背景:我们想对一个动作进行记录,记录的方式可能有多种,记录的顺序也有多种,例如:
这是一种记录方式

Controller Start:chouwu
start time: 1458124189349
Tank Start....
//Tank Moving这句是要被记录的动作
Tank Moving....
Tank Stop.....
end time: 1458124189395
Controller End:chouwu

这是另一种记录方式

Controller Start:chouwu
Tank Start....
start time: 1458124392063
//Tank Moving这句是要被记录的动作
Tank Moving....
end time: 1458124395385
Tank Stop.....
Controller End:chouwu

也有可能是这样的

Tank Start....
start time: 1458124479626
Controller Start:chouwu
//Tank Moving这句是要被记录的动作
Tank Moving....
Controller End:chouwu
end time: 1458124486154
Tank Stop.....

上述三种分别为LogProxy,TimeProxy,ControllerProxy,不仅它们的顺序会调换,可能还需要添加新的记录Proxy,还可能将Tank换成Car,有什么简单的修改方法能得到随心所欲的调换和添加
使用动态代理设计模式!
模式还是需要通过代码来理解:
Moveable接口

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

实现了Moveable接口的Tank

package com.chouwu;
import java.util.Random;
public class Tank implements Moveable {
    @Override
    public void move() {
        try {
            System.out.println("Tank Moving....");
            Thread.sleep(new Random().nextInt(10000));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

实现了Moveable接口的Car(Car和Tank区别很小,只是为了说明Moveable对象可调换)

package com.chouwu;
import java.util.Random;
public class Car implements Moveable {
    @Override
    public void move() {
        try {
            System.out.println("Car Moving....");
            Thread.sleep(new Random().nextInt(10000));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

实现了Moveable接口的LogProxy

package com.chouwu;
public class LogProxy implements Moveable{
    Moveable m;
    public LogProxy(Moveable m) {
        this.m = m;
    }
    @Override
    public void move() {
        System.out.println("Tank Start....");
        m.move();
        System.out.println("Tank Stop.....");
    }
}

实现了Moveable接口的TimeProxy

package com.chouwu;
public class TimeProxy implements Moveable{
    Moveable m;
    public TimeProxy(Moveable m) {
        this.m = m;
    }
    @Override
    public void move() {
        long start = System.currentTimeMillis();
        System.out.println("start time: " + start);
        m.move();
        long stop = System.currentTimeMillis();
        System.out.println("end time: " + stop);
    }
}

实现了Moveable接口的ControllerProxy

package com.chouwu;
public class ControllerProxy implements Moveable{
    Moveable m;
    String controller;
    public ControllerProxy(Moveable m,String controller) {
        this.m = m;
        this.controller = controller;
    }
    @Override
    public void move() {
        System.out.println("Controller Start:"+controller);
        m.move();
        System.out.println("Controller End:"+controller);
    }
}

注意,如何调换和更改记录的方式主要在主程序Client中,Client如下:
如果我记录Tank的行为,只记录时间和日志,并且先记录时间,后记录日志,那么Client中就这样调用:

package com.chouwu;
public class Client {
    public static void main(String[] args) {
        Tank t = new Tank();
        LogProxy lp = new LogProxy(t);
        TimeProxy tp = new TimeProxy(lp);
        tp.move();
    }   
}

结果如下

start time: 1458125789924
Tank Start....
Tank Moving....//这句是要被记录的动作
Tank Stop.....
end time: 1458125799718

如果我记录Tank的行为,记录时间、日志和控制者,并且先记录日志,后记录控制者和时间,那么Client中就这样调用:

package com.chouwu;
public class Client {
    public static void main(String[] args) {
        Tank t = new Tank();
        TimeProxy tp = new TimeProxy(t);
        ControllerProxy cp = new ControllerProxy(tp,"chouwu");
        LogProxy lp = new LogProxy(cp);
        lp.move();
    }   
}

结果

Tank Start....
Controller Start:chouwu
start time: 1458126074329
Tank Moving....
end time: 1458126076182
Controller End:chouwu
Tank Stop.....

如果有天有新的需求,需要我记录另一种实现了Moveable的类Car的行为,也是记录时间、日志和控制者,并且先记录时间,后记录日志,那么Client中就这样调用:

package com.chouwu;
public class Client {
    public static void main(String[] args) {
//      Tank t = new Tank();
        Car c = new Car();
        TimeProxy tp = new TimeProxy(c);
        ControllerProxy cp = new ControllerProxy(tp,"chouwu");
        LogProxy lp = new LogProxy(cp);
        lp.move();
    }   
}

结果:

Tank Start....
Controller Start:chouwu
start time: 1458126212160
Car Moving....
end time: 1458126217843
Controller End:chouwu
Tank Stop.....

由上可见,动态代理十分灵活的帮助我们实现了调序和随时增删代理的功能。Moveable统一了除测试外的所有的类,每个代理类中都聚合了一个实现了Moveable接口的对象,或是另一个代理,或是被代理的对象。当然,理解动态代理模式还是要依靠自己动手写程序来理解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值