一、内容提要
本文主要是对静态代理设计模式和装饰者设计模式进行比较,总结一下他们之间的相同和不同之处。
二、代码描述
如果对装饰者设计模式不太熟悉的同学,可以看之前的文章:装饰者设计模式(一)
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、功能增强的实现者不同:
装饰者设计模式中存在装饰者基类或父类,其并不真正实现增强,而是由具体的装饰者进行功能增强的,所以存在一个“装饰者链”的概念
静态代理设计模式中,一般不存在父子类的关系,具体的增强就是由代理类完成,无需由子类完成,所以不存在“链”的概念