WHWW之代理模式(1)-静态代理
What:什么是静态代理?
代理就是用于通过对真实对象的封装,对原有业务逻辑的扩充,来实现扩展性。。比如持有二方包的某个类,并调用了其中的某些方法。然后出于某种原因,比如记录日志、打印方法执行时间,但是又不好将这些逻辑写入二方包的方法里。所以可以创建一个代理类实现和二方方法相同的方法,通过让代理类持有真实对象,然后在原代码中调用代理类方法,来达到添加我们需要业务逻辑的目的。由于在程序运行前代理类就已经获得目标对象了,所以把这类称为静态代理。
How:怎么实现静态代理呢?
静态代理的类图:
根据类图我们可以实现静态代理
/** * 抽象角色接口 */ public interface Hello { /** * 打招呼 */ public void sayHello(); }
/** * 目标对象角色类 */ public class RealHello implements Hello { /** * 实现接口的方法 */ @Override public void sayHello() { System.out.println("你好"); } }
/** * 代理对象角色类 */ public class ProxyHello implements Hello { private Hello realHello; public ProxyHello(Hello realHello) { this.realHello = realHello; } /** * 实现接口的方法 */ @Override public void sayHello() { before(); realHello.sayHello(); after(); } /** * 在实现方法前可以做的事情 */ public void before(){ System.out.println("摘下耳机"); } /** * 在实现方法后做的事情 */ public void after(){ System.out.println("戴上耳机"); } }
/** * 客户端,实现代理模式 */ public class ProxyTest { public static void main(String[] args) { System.out.println("没有代理的,目标对象自己实现:"); Hello hello = new RealHello(); hello.sayHello(); System.out.println("========================="); System.out.println("代理对象实现的:"); ProxyHello proxyHello = new ProxyHello(hello); proxyHello.sayHello(); } }
控制台输出:
没有代理的,目标对象自己实现:
你好
=========================
代理对象实现的:
摘下耳机
你好
戴上耳机
Why:为什么要使用静态代理
首先我们可以想一下,如果不用代理模式,那么我们要实现sayHello()方法之前执行某些方法或者之后执行某些方法,就必须在目标对象角色把代码写死。目标对象类图就变为这样了:
也许我们想,这样写也没什么不好啊,而且写个代理类还增加了类的数量,维护工作不也增加了吗?但我们想想如果有大量的类要加类似代码,都这样写的话,那么我们工作量比较大,而且这样的类不容易重构,而且如果我们又要增加其他功能时,又得修改其他所有的类,所有扩展性比较低。所以这时候我们应该想到代理类,我们可以在不改变原目标类的情况下,为目标对象类增加额外的功能,如果我们要为目标对象再增加其他功能,我们可以又写另一个代理类就好了。这样代码的理解,重构,扩展性都比这样写死的代码好多了。
Where:哪些地方使用过静态代理?
保存用户功能可以使用静态代理实现
静态代理的优缺点:
优点:可以在不修改目标对象的前提下扩展目标对象的功能。
缺点:
- 冗余。由于代理对象要实现与目标对象一致的接口,会产生过多的代理类。
- 不易维护。一旦接口增加方法,目标对象与代理对象都要进行修改。
注:静态代理方式需要代理对象和目标对象实现一样的接口。