我们先来看一个案例。
有一个接口IService,如下:
package com.javacode2018.lesson001.demo15;public interface IService { void m1(); void m2(); void m3();}1234567
接口有2个实现类ServiceA和ServiceB,如下:
package com.javacode2018.lesson001.demo15;public class ServiceA implements IService { @Override public void m1() { System.out.println("我是ServiceA中的m1方法!"); } @Override public void m2() { System.out.println("我是ServiceA中的m2方法!"); } @Override public void m3() { System.out.println("我是ServiceA中的m3方法!"); }}package com.javacode2018.lesson001.demo15;public class ServiceB implements IService { @Override public void m1() { System.out.println("我是ServiceB中的m1方法!"); } @Override public void m2() { System.out.println("我是ServiceB中的m2方法!"); } @Override public void m3() { System.out.println("我是ServiceB中的m3方法!"); }}123456789101112131415161718192021222324252627282930313233343536
来个测试用例来调用上面类的方法,如下:
package com.javacode2018.lesson001.demo15;import org.junit.Test;public class ProxyTest { @Test public void m1() { IService serviceA = new ServiceA(); IService serviceB = new ServiceB(); serviceA.m1(); serviceA.m2(); serviceA.m3(); serviceB.m1(); serviceB.m2(); serviceB.m3(); }}123456789101112131415161718
上面的代码很简单,就不解释了,我们运行一下m1()方法,输出:
我是ServiceA中的m1方法!我是ServiceA中的m2方法!我是ServiceA中的m3方法!我是ServiceA中的m1方法!我是ServiceA中的m2方法!我是ServiceA中的m3方法!123456
上面是我们原本的程序,突然领导有个需求:调用IService接口中的任何方法的时候,需要记录方法的耗时。
此时你会怎么做呢?
IService接口有2个实现类ServiceA和ServiceB,我们可以在这两个类的所有方法中加上统计耗时的代码,如果IService接口有几十个实现,是不是要修改很多代码,所有被修改的方法需重新测试?是不是非常痛苦,不过上面这种修改代码的方式倒是可以解决问题,只是增加了很多工作量(编码 & 测试)。
突然有一天,领导又说,要将这些耗时统计发送到监控系统用来做监控报警使用。
此时是不是又要去一个修改上面的代码?又要去测试?此时的系统是难以维护。
还有假如上面这些类都是第三方以jar包的方式提供给我们的,此时这些类都是class文件,此时我们无法去修改源码。
比较好的方式:可以为IService接口创建一个代理类,通过这个代理类来间接访问IService接口的实现类,在这个代理类中去做耗时及发送至监控的代码,代码如下:
package com.javacode2018.lesson001.demo15;// IService的代理类public class ServiceProxy implements IService { //目标对象,被代理的对象 private IService target; public ServiceProxy(IService target