设计模式之美
王争
前 Google 工程师,《数据结构与算法之美》专栏作者
123425 人已学习
新⼈⾸单¥98
登录后,你可以任选6讲全文学习
课程目录
已完结/共 113 讲
设计模式与范式:行为型 (18讲)
设计模式之美
15
15
1.0x
00:00/00:00
登录|注册

51 | 适配器模式:代理、适配器、桥接、装饰,这四个模式有何区别?

对象适配器
类适配器
支持多个装饰器的嵌套使用
对原始类功能进行增强
将接口部分和实现部分分离
控制访问而非加强功能
为原始类定义一个代理类
适配器模式的应用
Slf4j日志框架
适配不同格式的数据
兼容老版本接口
替换依赖的外部系统
统一多个类的接口设计
封装有缺陷的接口设计
选择使用哪种实现方式的标准
适配器模式的两种实现方式
适配器模式的英文翻译是Adapter Design Pattern
装饰器模式的特点
桥接模式的特点
代理模式的特点
代理、桥接、装饰器、适配器4种设计模式的区别
适配器模式在Java日志中的应用
适配器模式应用场景总结
适配器模式的原理与实现
装饰器模式
桥接模式
代理模式
适配器模式

该思维导图由 AI 生成,仅供参考

前面几节课我们学习了代理模式、桥接模式、装饰器模式,今天,我们再来学习一个比较常用的结构型模式:适配器模式。这个模式相对来说还是比较简单、好理解的,应用场景也很具体,总体上来讲比较好掌握。
关于适配器模式,今天我们主要学习它的两种实现方式,类适配器和对象适配器,以及 5 种常见的应用场景。同时,我还会通过剖析 slf4j 日志框架,来给你展示这个模式在真实项目中的应用。除此之外,在文章的最后,我还对代理、桥接、装饰器、适配器,这 4 种代码结构非常相似的设计模式做简单的对比,对这几节内容做一个简单的总结。
话不多说,让我们正式开始今天的学习吧!

适配器模式的原理与实现

适配器模式的英文翻译是 Adapter Design Pattern。顾名思义,这个模式就是用来做适配的,它将不兼容的接口转换为可兼容的接口,让原本由于接口不兼容而不能一起工作的类可以一起工作。对于这个模式,有一个经常被拿来解释它的例子,就是 USB 转接头充当适配器,把两种不兼容的接口,通过转接变得可以一起工作。
原理很简单,我们再来看下它的代码实现。适配器模式有两种实现方式:类适配器和对象适配器。其中,类适配器使用继承关系来实现,对象适配器使用组合关系来实现。具体的代码实现如下所示。其中,ITarget 表示要转化成的接口定义。Adaptee 是一组不兼容 ITarget 接口定义的接口,Adaptor 将 Adaptee 转化成一组符合 ITarget 接口定义的接口。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

适配器模式是一种常用的结构型设计模式,用于解决接口不兼容的问题。本文深入介绍了适配器模式的原理与实现,包括类适配器和对象适配器两种实现方式,并提出了在实际开发中如何选择使用哪种方式的标准。此外,文章总结了适配器模式的5种常见应用场景,包括封装有缺陷的接口设计、统一多个类的接口设计以及替换依赖的外部系统。通过具体的代码示例,读者可以更好地理解适配器模式在实际项目中的应用。 除此之外,文章还深入剖析了适配器模式在Java日志中的应用,以及代理、桥接、装饰器、适配器4种设计模式的区别。特别是对于适配器模式与其他设计模式的区别进行了详细解释,帮助读者更好地理解这些模式的应用场景和目的。 总的来说,本文内容简洁清晰,适合读者快速了解适配器模式的概要及其技术特点,对于想要深入了解设计模式的开发人员具有一定的参考价值。适配器模式的灵活应用能够帮助开发人员解决接口不兼容的问题,提高代码的可维护性和扩展性。文章通过丰富的案例和对比分析,使读者能够更好地理解适配器模式的实际应用和优势,为他们在实际项目中的应用提供了有力的支持和指导。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《设计模式之美》
新⼈⾸单¥98
立即购买
登录 后留言

全部留言(81)

  • 最新
  • 精选
  • Laughing
    1. 代理模式中,委托类的实现基本上就是类代理的模式 2. 装饰器模式本身为了解决继承太深的问题,所以没有类装饰器的模式

    作者回复: 嗯嗯

    2020-11-20
    8
  • Obed
    王争老师 今天学习了这篇文章,你说slf4j会使用spi的技术动态指定具体使用哪一种框架。然后我查了一下资料,看了自己项目关于日志的源码。slf4j好像是指定了org.slf4j.impl这个包。然后在LoggerFactory.getLogger()的时候在去扫描实现了slf4j接口的日志的这个指定包去加载对应的类。这跟java的spi好像不大一样。还是说其实这种实现跟spi的思想都是一样的

    作者回复: 有可能是我理解错了,我再去核实一下,多谢指出!

    2020-07-14
    1
  • 有爱有波哥
    CD 实现代码不是接口是具体的方法吗?

    作者回复: 不是接口~

    2020-05-22
  • javaadu
    这篇总结将前几节课串联起来了,非常赞👍 课堂讨论: 1. 代理模式支持,基于接口组合代理就是对象匹配,基于继承代理就是类匹配 2. 装饰者模式不支持,这个模式本身是为了避免继承结构爆炸而设计的
    2020-02-28
    6
    119
  • 小晏子
    代理模式有两种实现方式:一般情况下,我们让代理类和原始类实现同样的接口。这种就是对象代理模式;但是,如果原始类并没有定义接口,并且原始类代码并不是我们开发维护的。在这种情况下,我们可以通过让代理类继承原始类的方法来实现代理模式,这种属于类代理模式。 装饰器模式没有这两种方式:装饰器模式主要解决继承关系过于复杂的问题,通过组合来替代继承,在设计的时候,装饰器类需要跟原始类继承相同的抽象类或者接口。所以装饰器只有对象装饰器这一种。
    2020-02-28
    2
    65
  • 阿骨打
    说实话真的牛,看到51节,争哥的水平估计高于99.9%的码农了,能懂是一层境界,能说给别人听,使别人信服是一层境界,能串联起来说给别人听,又是一层境界。
    2020-09-18
    8
    34
  • 唐龙
    C++的STL里有大量的适配器,比如迭代器适配器,容器适配器,仿函数适配器。 容器里的反向迭代器reverse_iterator就是对迭代器iterator的一层简单封装。 所谓的栈stack和单向队列queue也是对其他容器的封装,底层默认使用的是双向队列deque,两者也都可以选用双向链表list,stack也可以使用向量vector。可以通过模板参数选用具体的底层容器,比如stack<int, vector<int>> stk;。 而仿函数适配器functor adapter则是其中的重头戏,众所周知,仿函数functor是一种重载了函数调用运算符的类。仿函数适配器可以改变仿函数的参数个数,比如bind1st, bind2nd等。 一个使用仿函数适配器的例子: count_if(scores.begin(),scores.end(),bind2nd(less<int>(), 60)); 上述代码翻译成人话就是统计不到60分成绩的人数。 正常来讲,不论count_if的最后一个参数是函数指针还是仿函数对象,只能接受一个参数,我们没必要为“小于60”这么微不足道的事情单独写一个函数或是仿函数,所以选择了通过bind2nd这一个适配器改变函数的参数个数,并且把其中的第二个参数绑定为60。 STL使用适配器的目的是为了更灵活的组合一些基础操作,并不是设计缺陷。 所以对于老师所说的 ……适配器模式可以看作一种“补偿模式”,用来补救设计上的缺陷。应用这种模式算是“无奈之举”…… 我并不认同。
    2020-02-28
    5
    32
  • 勤劳的明酱
    那SpringAop是代理模式,主要功能却是增强被代理的类,这不是更符合装饰器模式。
    2020-02-28
    7
    18
  • honnkyou
    1 中的代码ITarget应该是接口吧
    2020-03-17
    1
    16
  • 每天晒白牙
    代理模式有两种实现方式 1.代理类和原始类实现相同的接口,原始类只负责原始的业务功能,而代理类通过委托的方式调用原始类来执行业务逻辑,然后可以做一些附加功能。这也是一种基于接口而实现编程的设计思想。这就是基于组合也就是对象模式 2.如果原始类没有定义接口且不是我们开发维护的,这属于对外部类的扩展,可以使用继承的方式,只需要用代理类继承原始类,然后附加一些功能。这就是基于类模式 装饰者模式主要解决的问题就是继承关系过于复杂,通过组合来代替继承,主要作用是给原始类添加增强功能。所以装饰者模式只有对象模式
    2020-02-28
    1
    11
收起评论
显示
设置
留言
81
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部