背景
写了一篇关于mybatis缓存的文章,发现里面的executor和cache都用到了装饰器模式,所以准备专门写一篇装饰器模式的文章,以cache为例
定义
动态地给一个对象添加一些额外的职责。 就增加功能来说,装饰模式相比生成子类更为灵活
使用场景:
- 需要扩展一个类的功能,或给一个类增加附加功能。
- 需要动态地给一个对象增加功能,这些功能可以再动态地撤销。
- 需要为一批的兄弟类进行改装或加装功能,当然是首选装饰模式。
源码说明
现在用源码类说明一下是怎么实现的,我们来看一下MapperBuilderAssistant的useNewCache和CacheBuilder的setStandardDecorators方法
由上面的代码我们可以知道,分别对PerpetualCache做了BlockingCache ->SynchronizedCache ->LoggingCache -> SerializedCache ->ScheduledCache ->LruCache -> PerpetualCache装饰,我们来看看这些装饰类的功能
- BlockingCache: 使用ReentrantLock来防止高速缓存未命中时对数据库的大规模访问,它设置了对高速缓存键的锁定
- SynchronizedCache:同步Cache,实现比较简单,直接使用synchronized修饰方法。
- LoggingCache:日志功能,装饰类,用于记录缓存的命中率,如果开启了DEBUG模式,则会输出命中率日志。
- SerializedCache:序列化功能,将值序列化后存到缓存中。该功能用于缓存返回一份实例的Copy,用于保存线程安全。
- LruCache:采用了Lru算法的Cache实现,移除最近最少使用的Key/Value。
- ScheduledCache:设置定时刷新缓存。
- PerpetualCache: 作为最基础的缓存类,底层实现比较简单,直接使用了HashMap。
可以发现,最终的操作都是委托给PerpetualCache来做的,其它的装饰器只是附带了一些格外的功能