目录
前言
装饰器模式与代理模式的区别
UML
plantuml
类图
实战代码
mybatis cache
前言
装饰器模式和代理模式在使用上很相似,都是在不修改原始类代码的情况下,动态地给真实对象的方法做增强。
装饰器模式是通过创建一个包装对象来包裹原有对象,并在包装对象中添加额外的职责。装饰器可以有多个,在实际使用中,可以根据不同的场景,使用多个不同的装饰器包装来实现需求。
装饰器模式与代理模式的区别
装饰器做功能增强的颗粒度更细,而且可以多次装饰,更加地灵活,代理模式则只能对真实对象做一次功能增强。
装饰器的使用对于客户端来说是 “有感” 的,客户端在使用装饰器时,必须知道各个装饰器的作用,并根据不同的需求来使用装饰器,而代理对象的使用则是 “无感” 的,客户端并不关心调用的方法做了什么功能增强。
UML
plantuml
@startuml 'https://plantuml.com/class-diagraminterface Component {+ operation() : void }class ConcreteComponent {+ operation() : void }class ConcreteDecoratorA {- component : Component+ ConcreteDecoratorA(Component)+ operation() : void }class ConcreteDecoratorB {- component : Component+ ConcreteDecoratorB(Component)+ operation() : void }Component <|.. ConcreteComponent Component <|.. ConcreteDecoratorA Component <|.. ConcreteDecoratorBClient ..> Component@enduml
类图
实战代码
mybatis cache
mybatis 如果开启了二级缓存的话,每次查询就会先从二级缓存先查找,二级缓存就是用装饰器模式设计的。
相关接口和类如下,可以看到顶层接口 Cache,还有一个基本实现 PerpetualCache,其他的 Cache 全都是装饰器,mybatis会根据配置来选择不同的装饰器修饰。
创建二级缓存的核心代码
MapperBuilderAssistant 的 useNewCache 方法
可以看到使用了建造者模式 CacheBuilder 来构造二级缓存
CacheBuilder
最终的 build 方法
其中的 setStandardDecorators 方法,根据不同的配置,使用了不同的装饰器来修饰二级缓存,实现不同的功能