装饰模式对象组合的特点:
- 1、装饰类和被装饰类继承同样的父类,或者实现相同的接口
- 2、装饰类的作用是进行功能的增强而不是提供额外的功能
Mybatis 中的装饰器
Mybaits 中基础支持层提供有缓存组件功能,而缓存组件功能的实现就是以装饰者模式实现的,如下图:![[设计模式]-[结构型]-装饰-应用案例 - 图1](/uploads/projects/it-learn@java-base/631ff65fed2760d7e6f0fb6ce022fce3.webp)
所有缓存的组件都实现自同一个接口 Cache。
所有缓存组件中,最基础的组件实现就是 PerpetualCache![[设计模式]-[结构型]-装饰-应用案例 - 图2](/uploads/projects/it-learn@java-base/7ef8d72ebb636f1878e8129697a2711b.webp)
如上图, PerpetualCache直接通过 HashMap 容器实现的缓存功能,也是最基础不具备任何功能的缓存。
线程安全的缓存组件
基础缓存组件 PerpetualCache 无法提供线程安全功能,Mybatis 使用装饰者的模式,在此基础上实现了线程安全功能的装饰类SynchronizedCache,代码如下:![[设计模式]-[结构型]-装饰-应用案例 - 图3](/uploads/projects/it-learn@java-base/9ed3e2dcdd736d8dc2f84fa0e4d664c2.webp)
代码本身不具备缓存能力,只是对具有缓存能力的类进行功能的增强。
具有 LRU 功能的缓存组件
基础缓存组件 PerpetualCache 无法提供 LRU 算法功能,Mybaits 使用装饰者模式,提供了 LRU 算法功能,LruCache 代码如下:
![[设计模式]-[结构型]-装饰-应用案例 - 图4](/uploads/projects/it-learn@java-base/682b24b1e835c4b239d90a02bc32f124.webp)
同样的 LruCache 本身不具备缓存能力,只是对于有缓存能力的类进行功能增强。
以此类推,需要啥功能就使用装饰者模式增加功能即可,Mybatis 还实现了具有日志打印功能的 LoggingCache,周期性清除缓存功能的 ScheduledCache
上述的缓存功能,如 LRU,线程安全,不仅仅适用于基础缓存组件 PerpetualCache ,而是适用于任何一个具有缓存能力的缓存组件,
比如:一个同时具有 LRU ,线程安全,日志打印功能的缓存组件,如下图:![[设计模式]-[结构型]-装饰-应用案例 - 图5](/uploads/projects/it-learn@java-base/b487a04774e905a01df9f9199246bdad.webp)
同理,如果需要在追加功能,只需要在增加一个装饰类,然后在往缓存组件外层套用即可。
【公众号】花好夜猿
