设计模式-Adapter适配器模式和Decorator装饰者模式

268 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第12天,点击查看活动详情

1.适配器模式

1.1 适配器的作用

适配器模式的作用是把两个不兼容的对象通过适配器能够连接起来工作。

image.png

1.2 具体案例分析

以MyBatis中的日志模块为例来介绍。常见的日志框架有log4j,log4j2,slf4j,logbak等,但是每种日志框架中的日志级别都有差异。

log4j2的接口:

image.png

slf4j的接口

image.png

也就是可以看到不同的日志框架里面所定义的日志级别和对应的方法都有区别,那么我们的框架怎么来统一使用这些日志框架呢?在MyBatis中通过定义了一个日志接口,定义了日志具有的级别和方法。

image.png

那这时候我们就发现具体的日志框架和这个接口其实是没有办法直接来使用的。

image.png

这时我们就需要通过对应的适配器来处理这种情况,以Slf4J为例。

image.png

2.装饰者模式的理解

2.1 装饰者模式的作用

装饰者模式又称为包装模式(Wrapper),作用是用来动态的为一个对象增加新的功能。装饰模式是一种用于代替继承的技术, 无须通过继承增加子类就能扩展对象的新功能 。使用对象的关联关系代替继承关系,更加灵活,同时避免类型体系的快速膨胀。

image.png

2.2 装饰者模式的应用

装饰者模式的应用场景还是非常多的,比如

  • IO流中的FileInputStream,FileOutputStream等
  • Spring中的各种Wrapper
  • MyBatis中的缓存设计

我们以MyBatis中的缓存实例为例来看看其具体的实现。

首先是Cache接口

image.png

然后是PerpetualCache实现:仅仅实现了数据基于内存的读写操作。功能单一。

image.png

装饰类:然后在MyBatis中给我们提供了很多的装饰类。

image.png

每个装饰类都有自己的作用

  • BlockingCache:阻塞的
  • LruCache:根据Lru规则来淘汰缓存数据
  • FifoCache:根据FIFO规则来淘汰缓存数据
  • ....

源码中的装饰:

image.png

image.png

比较说明
优点1. 扩展对象功能,比继承灵活,不会导致类个数急剧增加2. 可以对一个对象进行多次装饰,创造出不同行为的组合,得到功能更加强大的对象<br />3. 具体构建类和具体装饰类可以独立变化,<br />用户可以根据需要自己增加新的具体构件子类和具体装饰子类。
缺点1. 产生很多小对象。大量小对象占据内存,一定程度上影响性能。2. 装饰模式易于出错,调试排查比较麻烦。