一、内容提要
本文主要是对静态代理设计模式和装饰者设计模式进行比较,总结一下他们之间的相同和不同之处。
二、代码描述
如果对装饰者设计模式不太熟悉的同学,可以看之前的文章:装饰者设计模式(一)
1、开发简单的装饰者类
目标类接口ISomeService
package com.proxy; /** * 业务逻辑接口 */ public interface ISomeService { //目标方法 String doSome(); }
目标实现类SomeService
package com.proxy; /** * 目标类 */ public class SomeService implements ISomeService { @Override public String doSome() { return "abcde"; } }
装饰者类SomeServiceDecorator
package com.decorator; /** * 装饰者: * 1、装饰者类与目标类要实现相同的接口,或继承自相同的抽象类 * 2、装饰者类中要有目标类的引用作为成员变量,而具体的实现一般通过带参构造器完成 */ public class SomeServiceDecorator implements ISomeService { //目标对象 private ISomeService target; //通过带参构造器传入目标对象 public SomeServiceDecorator(ISomeService target) { this.target = target; } @Override public String doSome() { return target.doSome().toUpperCase(); } }
2、开发简单的静态代理类
目标类接口和目标实现类,其实和上面一样的,我还是再写一遍吧,防止大家看蒙了
目标类接口ISomeService
package com.proxy; /** * 业务逻辑接口 */ public interface ISomeService { //目标方法 String doSome(); }
目标实现类SomeService
package com.proxy; /** * 目标类 */ public class SomeService implements ISomeService { @Override public String doSome() { return "abcde"; } }
静态代理类SomeServiceProxy
package com.proxy; /** * 静态代理类: */ public class SomeServiceProxy implements ISomeService { private ISomeService target; // 在无参构造器中直接创建目标对象,对外界隐藏目标类对象 public SomeServiceProxy() { this.target = new SomeService(); } @Override public String doSome() { return target.doSome().toUpperCase(); } }
测试类跑一下
package com.proxy; public class Test { public static void main(String[] args) { ISomeService target = new SomeServiceProxy(); System.out.println(target.doSome());//ABCDE } }
三、区别
静态代理模式和装饰者模式,最本质的区别就是 创建对象的方式不一样。
首先 装饰者模式,创建对象是通过带参构造器来实现的。
public class SomeServiceDecorator implements ISomeService { //目标对象 private ISomeService target; //通过带参构造器传入目标对象 public SomeServiceDecorator(ISomeService target) { this.target = target; }
而 静态代理模式 是通过无参构造器,直接创建的,目的是为了保护和隐藏目标类对象
public class SomeServiceProxy implements ISomeService { private ISomeService target; // 在无参构造器中直接创建目标对象,对外界隐藏目标类对象 public SomeServiceProxy() { this.target = new SomeService(); }
细心的同学会发现,测试类中,并没有看到目标实对象,而是只看到了代理类,这就是为了隐藏对象而设计的
public static void main(String[] args) { //没有看到目标类对象SomeService ,只有代理类SomeServiceProxy ISomeService target = new SomeServiceProxy(); System.out.println(target.doSome());//ABCDE }
四、总结
相同点:
1、都要实现与目标类相同的业务接口
2、这两个类中都要声明目标对象
3、都可以在不修改目标类的前提下增强目标方法
区别:
1、目的不同:装饰者的使用目的就是增强目标对象;而静态代理类的目的是为了保护和隐藏目标对象
2、对目标对象的获取方式不同:
装饰者类中目标对象的获取,是通过带参构造器来传入
静态代理类中目标对象的获取,是直接在无参构造器中创建,而非用户传过来的,因为要保护和隐藏对象。
3、功能增强的实现者不同:
装饰者设计模式中存在装饰者基类或父类,其并不真正实现增强,而是由具体的装饰者进行功能增强的,所以存在一个“装饰者链”的概念
静态代理设计模式中,一般不存在父子类的关系,具体的增强就是由代理类完成,无需由子类完成,所以不存在“链”的概念