1、概念
装饰器模式是在不修改原类的情况下,通过添加新的装饰器类,对原有功能进行扩展。
它的主要应用场景是同一对象从不同角度去归类时,需要不同的功能和处理方式,而对象的具体类型是运行阶段时决定的。
装饰器模式的类结构不复杂,但是代码实现会很复杂,因为它基于对原始类的认知。
原始类的认知可以抽象为三个方面:
1. 划分的角度
2. 基于划分角度的对象归类
3. 不同种类的功能,以及处理方式
例如HttpRequest对象,从响应的内容可以分为静态资源请求时,数据请求。从请求的数据类型可以划分为二进制流请求,其他数据类型请求(大部分为字符串)。从请求方式的角度,可以划分为GET,POST,PUT,DELETE等请求。依据不同的请求类型,它们的处理方式也是不同的。
2、UML图

3、代码
XXInterface,被装饰的接口类
/**
*
* @File Name: SomeInterface.java
* @Description: 某个被装饰的接口, 如果是Web应用时,可以理解它扮演着ServletRequest或者是HttpServletRequest的作用
* @version 1.0
* @since JDK 1.8
*/
public interface SomeInterface {
// 实现某个功能
void func();
}
XXInterfaceImpl,被装饰的接口实现类
/**
*
* @File Name: SomeInterfaceImpl.java
* @Description: 具体的实现类,对应ServletRequestWrapper
* @version 1.0
* @since JDK 1.8
*/
public class SomeInterfaceImpl implements SomeInterface{
@Override
public void func() {
}
}
SomeDecoratorInterface,扮演者装饰器接口的角色,通常提供附加的功能
/**
*
* @File Name: SomeDecoratorInterface.java
* @Description: 装饰器接口,当为
* @version 1.0
* @since JDK 1.8
*/
public interface SomeDecoratorInterface extends SomeInterface {
// 例如针对MultiPart附加的一些额外方法,当没有附加功能时,此接口可以不存在
// 例如在Servlet中,ServletRequestWrapper直接实现ServletRequest接口,就没有与这个类相同职责的接口
void addtionalFunc();
}
SomeDecorateImpl,扮演者装饰器类的角色,若只想修改功能的实现方式,它可以实现被装饰的接口,此时装饰器接口没有存在的意义。
/**
*
* @File Name: SomeDecorateImpl.java
* @Description: 装饰器接口实现类,扮演着装饰器类的角色。这里它主要的职责是附加了额外的功能,addtionalFunc
* 例如常见的缓存功能。
* @version 1.0
* @since JDK 1.8
*/
public class SomeDecorateImpl implements SomeDecoratorInterface {
// 被装饰的原始类,在Web中相当于ServletRequest或HttpServletRequest
private SomeInterface someInterface;
public SomeDecorateImpl(SomeInterface someInterface) {
this.someInterface = someInterface;
}
@Override
public void func() {
someInterface.func();
}
@Override
public void addtionalFunc() {
// 额外功能的具体实现
}
}
个人建议去分析MultiPartRequest与ServletRequest的
4、讨论
问题1:装饰器模式的主要功能是?
答:在不修改原类的基础上添加附加的功能,或者修改已有功能的实现方式。
问题2:对装饰器模式的一些理解
答:装饰器模式的类结构不是很复杂,但是它很难,因为要达到全面认识原始类很难。
装饰器模式的”装饰”是不限制层次的,所以装饰器类是可以再次被装饰的,但是不建议这样,因为会导致类结构变的很复杂。
装饰器模式中被装饰的类或对象最好是顶层类或顶层接口,附加的功能最好是提供额外的接口进行继承,并提供默认的抽象类实现此接口,这样新增的装饰器类只需要继承抽象类,实现附加功能即可。
5、示例
1. Servlet或HttpServlet的类结构体系。
2. IO中inputStream和OutputStream的类结构体系。