装饰模式是一种结构型设计模式、允许你通过将对象放入包含行为的特殊封装对象中来为原来帝乡绑定新的行为。俗称套娃。
装饰模式中、封装器实现了与其封装对象相同的接口、封装器的成员变量可以是该接口的任意实现。
Mybatis 中的装饰模式
Cache 接口是 Mybatis 缓存中顶层的抽象接口、定义了 Mybatis 缓存最核心最基础的行为
public interface Cache {
String getId();
void putObject(Object key, Object value);
Object getObject(Object key);
Object removeObject(Object key);
void clear();
int getSize();
default ReadWriteLock getReadWriteLock() {
return null;
}
}
在实现类中、除了 PerpetualCache
之外、其他都是装饰器。PerpetualCache
内部则是简单的使用 Map 来做缓存
适用场景
- 为对象新增功能并且无需修改原有对象的代码的时候
- 使用继承的方式来扩展对象的行为行不通的时候、可以试试装饰模式
优点
- 无需新增子类即可扩展对象行为
- 运行时增删对象行为
- 单一职责、多个功能行为分别放在不同的装饰器中
缺点
- 客户端初始化各层装饰器的时候代码看上去会很糟糕
与其他模式的关系
- 适配模式可以对已有对象的接口进行修改(被适配的接口的方法跟应用实际使用的接口不一样)、装饰模式则能在不改变对象接口的前提下强化对象的功能、支持递归组合
- 装饰和代理有着相似的接口、但是其意图却非常不同、这两个模式都是基于组合原理、也就是说一个对象将部分工作委派给另一个对象、两者之间不同之处在于代理通常自行管理其服务对象的生命周期、而装饰的生成则是由客户端控制的。
- 责任链和装饰模式类结构非常相似、两者都依赖递归组合将需要执行的操作传递给一系列对象、但是两者有几点重要的不同之处。责任链管理者可以相互独立地执行一切操作、还可以随时停止传递请求。另一方面装饰模式可以在遵循基本接口的情况下扩展对象行为、此外、装饰模式没法中断请求的传递