package cn.edu.hpu.proxy; public interface Moveable { void move(); }
package cn.edu.hpu.proxy; import java.util.Random; public class Tank implements Moveable{ @Override public void move() { System.out.println("坦克正在移动中..."); try { //睡眠10秒以内的随机时间,表示坦克正在移动中 Thread.sleep(new Random().nextInt(10000)); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
大家很容易想到的是,在方法刚刚执行后和就要结束之前计算一下当前时间,然后相减获得执行时间:
@Override public void move() { long start=System.currentTimeMillis(); System.out.println("坦克正在移动中..."); try { //睡眠10秒以内的随机时间,表示坦克正在移动中 Thread.sleep(new Random().nextInt(10000)); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } long end=System.currentTimeMillis(); System.out.println("运行时间:"+(end-start)+"ms"); }那么,如果不允许修改move中的方法呢?比如说这个方法是别人的包里提供给你的,是人家已经写好的源代码,就编译了class给你,就没有给你源码,你没法在源码上修改怎么办?解决这件事情之前,我们先写一个测试类:
package cn.edu.hpu.proxy; public class Client { public static void main(String[] args) { Moveable m=new Tank(); m.move(); } }不要求计算move()方法执行的时间(JDK为其准备的时间等...),要计算内部代码执行的时间。
package cn.edu.hpu.proxy; public class Tank2 extends Tank{ @Override public void move() { long start=System.currentTimeMillis(); super.move(); long end=System.currentTimeMillis(); System.out.println("运行时间:"+(end-start)+"ms"); } }用继承来实现把原来的方法前后加一些逻辑,这是一种方式,是没有问题的。
package cn.edu.hpu.proxy; public class Tank3 implements Moveable{ Tank t; public Tank3(Tank t) { super(); this.t = t; } @Override public void move() { long start=System.currentTimeMillis(); t.move(); long end=System.currentTimeMillis(); System.out.println("运行时间:"+(end-start)+"ms"); } }上面一个使用继承来实现,一个是一个类存有另外一个类的对象,叫聚合。
由于Tank3它是记录时间的,而且是Tank的一个代理类,所以我们给它换一个名字,叫"TankTimeProxy"类。
package cn.edu.hpu.proxy; public class TankTimeProxy implements Moveable{ Tank t; public TankTimeProxy(Tank t) { super(); this.t = t; } @Override public void move() { long start=System.currentTimeMillis(); System.out.println("开始时间:"+start+"ms"); t.move(); long end=System.currentTimeMillis(); System.out.println("运行时间:"+(end-start)+"ms"); } }
package cn.edu.hpu.proxy; public class TankLogProxy implements Moveable{ Tank t; public TankLogProxy(Tank t) { super(); this.t = t; } @Override public void move() { System.out.println("坦克准备移动..."); t.move(); System.out.println("坦克移动结束..."); } }下面我们要对日志进行叠加,规定先先记录时间,再记录日志,怎么办?需要在写一个Tank3去继承Tank2(里面已经包含了时间记录代理),然后把日志记录代码加在move方法前后。如果规定先记录日志,再记录时间,怎么办?又要创建一个Tank4,继承Tank类,然后把日志记录代码加在move方法前后,之后再创建Tank5继承自Tank4,在在move方法前后加上时间记录代码.....你会发现,用继承的方式实现代理的话,这个类会无限制的增加下去,各种各样的代理功能如果想实现叠加的话,这个类要无限的往下继承,无边无际了...
TankTimeProxy:
package cn.edu.hpu.proxy; public class TankTimeProxy implements Moveable{ Moveable t; public TankTimeProxy(Moveable t) { super(); this.t = t; } @Override public void move() { long start=System.currentTimeMillis(); System.out.println("开始时间:"+start+"ms"); t.move(); long end=System.currentTimeMillis(); System.out.println("运行时间:"+(end-start)+"ms"); } }
package cn.edu.hpu.proxy; public class TankLogProxy implements Moveable{ Tank t; public TankLogProxy(Tank t) { super(); this.t = t; } @Override public void move() { System.out.println("坦克准备移动..."); t.move(); System.out.println("坦克移动结束..."); } }
Moveable t=new TankTimeProxy(new TankLogProxy(new Tank())); t.move();运行TankTimeProxy的move方法时,
@Override public void move() { long start=System.currentTimeMillis(); System.out.println("开始时间:"+start+"ms"); //此时t指向TankLogProxy类,调用的是TankLogProxy类的move方法 t.move(); long end=System.currentTimeMillis(); System.out.println("运行时间:"+(end-start)+"ms"); }我们知道TankLogProxy类的move方法是这样的(也就是上面的t.move();):
@Override public void move() { System.out.println("坦克准备移动..."); //这里的t指向的是Tank,所以执行的是Tank的move方法 t.move(); System.out.println("坦克移动结束..."); }
</pre><pre name="code" class="java">@Override public void move() { long start=System.currentTimeMillis(); System.out.println("开始时间:"+start+"ms"); System.out.println("坦克准备移动..."); //Tank的move方法 t.move(); System.out.println("坦克移动结束..."); long end=System.currentTimeMillis(); System.out.println("运行时间:"+(end-start)+"ms"); }
package cn.edu.hpu.proxy; import java.util.Random; public class Tank implements Moveable{ @Override public void move() { System.out.println("坦克正在移动中..."); try { //睡眠10秒以内的随机时间,表示坦克正在移动中 Thread.sleep(new Random().nextInt(10000)); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
package cn.edu.hpu.proxy; public class Client { public static void main(String[] args) { Moveable t=new TankTimeProxy(new TankLogProxy(new Tank())); t.move(); } }
package cn.edu.hpu.proxy; public interface Moveable { void move(); void stop(); }
package cn.edu.hpu.proxy; import java.util.Random; public class Tank implements Moveable{ @Override public void move() { System.out.println("坦克正在移动中..."); try { //睡眠10秒以内的随机时间,表示坦克正在移动中 Thread.sleep(new Random().nextInt(10000)); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override public void stop() { System.out.println("坦克停止中..."); } }
package cn.edu.hpu.proxy; public class TankTimeProxy implements Moveable{ Moveable t; public TankTimeProxy(Moveable t) { super(); this.t = t; } @Override public void move() { long start=System.currentTimeMillis(); System.out.println("开始时间:"+start+"ms"); t.move(); long end=System.currentTimeMillis(); System.out.println("运行时间:"+(end-start)+"ms"); } @Override public void stop() { long start=System.currentTimeMillis(); System.out.println("开始时间:"+start+"ms"); t.stop(); long end=System.currentTimeMillis(); System.out.println("运行时间:"+(end-start)+"ms"); } }
package cn.edu.hpu.proxy; public class TankTimeProxy implements Moveable{ Moveable t; long start; long end; public TankTimeProxy(Moveable t) { super(); this.t = t; } public void before(){ start=System.currentTimeMillis(); System.out.println("开始时间:"+start+"ms"); } public void after(){ end=System.currentTimeMillis(); System.out.println("运行时间:"+(end-start)+"ms"); } @Override public void move() { this.before(); t.move(); this.after(); } @Override public void stop() { this.before(); t.stop(); this.after(); } }
转载请注明出处:http://blog.csdn.net/acmman/article/details/46827819