Java 动态代理模式浅析

代理设计模式的UML图:

clipboard1-28

我将首先介绍Java中的各种代理实现方法

Java代理设计模式 - 静态代理

这个例子非常简单,只有一个方法wirteCode的接口IDeveloper:

public interface IDeveloper { public void writeCode(); } // 实现这个接口的类: public class Developer implements IDeveloper{ private String name; public Developer(String name){ this.name = name; } @Override public void writeCode() { System.out.println("Developer " + name + " writes code"); } }

测试代码:

public class DeveloperTest { public static void main(String[] args) { IDeveloper jerry = new Developer("Jerry"); jerry.writeCode(); } }

测试输出:

Developer Jerry writes code

现在麻烦的是,Jerry的领导因为团队中的开发者像Jerry一样没有编写技术文档,所以并不满意。经过讨论后,整个团队达成协议,相关文档必须与代码一起提供。

为了迫使开发人员编写文档而不直接对现有的实现类Developer进行修改,现在就可以使用静态代理来实现:

// 创建一个和Developer类实现同样接口的类 public class DeveloperProxy implements IDeveloper{ private IDeveloper developer; // 引用Developer类对象 public DeveloperProxy(IDeveloper developer){ this.developer = developer; } @Override public void writeCode() { System.out.println("Write documentation..."); this.developer.writeCode(); } }

测试代码:

public class DeveloperTest { public static void main(String[] args) { Developer jerry = new Developer("jerry"); DeveloperProxy jerryproxy = new DeveloperProxy(jerry); jerryproxy.writeCode(); } }

测试输出:

Write documentation... Developer jerry writes code 静态代理的优点

假设你希望在不修改原始类代码的情况下增强现有的稳定实现,你可以创建一个代理类,并将原始实现封装为代理中的私有属性。增强的功能是在代理类中完成的,对现有的代码是完全透明的。回到上面的示例,客户端代码并不关心它用来调用writeCode()方法的变量是否指向真正的开发人员或开发人员代码。

clipboard1-29

优点:

易于实施和理解

原始实现与其代理之间的关系在编译时已经确定,运行时没有额外的开销。

静态代理的缺点

我们仍然使用这个例子来说明。
假设现在缺失文档的问题在QA同事中仍然存在。如果我们想通过静态代理来解决这个问题,那么必须引入另一个代理类。

这是测试人员的接口:

public interface ITester { public void doTesting(); } // ITester 接口的实现类: public class Tester implements ITester { private String name; public Tester(String name){ this.name = name; } @Override public void doTesting() { System.out.println("Tester " + name + " is testing code"); } }

测试人员代理:

public class TesterProxy implements ITester{ private ITester tester; public TesterProxy(ITester tester){ this.tester = tester; } @Override public void doTesting() { System.out.println("Tester is preparing test documentation..."); tester.doTesting(); } }

测试代码和输出:

clipboard1-30

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/a75c20301a08ed19ab00d05881e1ae82.html