前端:Adapter(适配器模式)

Adapter(适配器模式)属于结构型模式,别名 wrapper,结构性模式关注的是如何组合类与对象,以获得更大的结构,我们平常工作大部分时间都在与这种设计模式打交道。

意图:将一个类的接口转换成客户希望的另一个接口。Adapter 模式使得原本由于接口不兼容而不能在一起工作的那些类可以一起工作。

这个设计模式的意图很好懂,就是把接口不兼容问题抹平。注意,也仅仅能解决接口不一致的问题,而不能解决功能不一致的问题。

举例子

如果看不懂上面的意图介绍,没有关系,设计模式需要在日常工作里用起来,结合例子可以加深你的理解,下面我准备了三个例子,让你体会什么场景下会用到这种设计模式。

接口转换器

插座的种类很多,我们都用过许多适配器,将不同的插头进行转换,可以在不替换插座的情况下正常使用。

USB 接口转换也同样精彩,有将 TypeC 接口转换为 TypeA 的,也有将 TypeA 接口转换为 TypeC 的,支持双向转换。

接口转换器就是我们在生活中使用到的适配器模式,因为厂商并没有生产一个新的插座,我们也没有因为接口不适配而换一个手机,一切只需要一个接口转换器即可,这就是运用设计模式的收益。

数据库 ORM

ORM 屏蔽了 SQL 这一层,带来的好处是不需要理解不同 SQL 语法之间的区别,对于通用功能,ORM 会根据不同的平台,比如 Postgresql、Mysql 进行 SQL 的转换。

对 ORM 来说,屏蔽不同平台的差异,就是利用适配器模式做到的。

API Deprecated

当一个广泛使用的库进行了含有 break change 的升级时,往往要留给开发者足够的时间去升级,而不能升级后就直接挂掉,因此被废弃的 API 要标记为 deprecated,而这种被废弃标记的 API 的实际实现,往往是使用新的 API 替代,这种场景正是使用了适配器模式,将新的 API 适配到旧的 API,实现 API Deprecated。

意图解释

上面三个例子都满足下面两个条件:

  1. API 不兼容:因为接口的不同;数据库 SQL 语法的不同;框架 API 的不同。
  2. 但能力已支持:插座都拥有充电或读取能力;不同的 SQL 都拥有查询数据库能力;新 API 覆盖了旧 API 的能力。

这样就可以通过适配器满足 Adapter 的意图:

意图:将一个类的接口转换成客户希望的另一个接口。Adapter 模式使得原本由于接口不兼容而不能在一起工作的那些类可以一起工作。

结构图

适配器的实现分为继承与组合模式。

下面是名词解释:

  • Adapter 适配器,把 Adeptee 适配成 Target
  • Adaptee 被适配的内容,比如不兼容的接口。
  • Target 适配为的内容,比如需要用的接口。

继承:

适配器继承 Adaptee 并实现 Target,适用场景是 AdapteeTarget 结构类似的情况,因为这样只需要实现部分差异化即可。

组合:

组合的拓展性更强,但工作量更大,如果 TargetAdaptee 结构差异较大,适合用组合模式。

代码例子

下面例子使用 typescript 编写。

继承:

interface ITarget {
  // 标准方式是 hello
  hello: () => void
}

class Adaptee {
  // 要被适配的类方法叫 sayHello
  sayHello() {
    console.log('hello')
  }
}

// 适配器继承 Adaptee 并实现 ITarget
class Adapter extends Adaptee implements ITarget {
  hello() {
    // 用 sayHello 对接到 hello
    super.sayHello()
  }
}

组合:

interface ITarget {
  // 标准方式是 hello
  hello: () => void
}

class Adaptee {
  // 要被适配的类方法叫 sayHello
  sayHello() {
    console.log('hello')
  }
}

// 适配器继承 Adaptee 并实现 ITarget
class Adapter implements ITarget {
  private adaptee: Adaptee 

  constructor(adaptee: Adaptee) {
    this.adaptee = adaptee
  }

  hello() {
    // 用 adaptee.sayHello 对接到 hello
    this.adaptee.sayHello()
  }
}

弊端

使用适配器模式本身就可能是个问题,因为一个好的系统内部不应该做任何侨界,模型应该保持一致性。只有在如下情况才考虑使用适配器模式:

  1. 新老系统接替,改造成本非常高。
  2. 三方包适配。
  3. 新旧 API 兼容。
  4. 统一多个类的接口。一般可以结合工厂方法使用。

总结

适配器模式也符合开闭原则,在不对原有对象改造的前提下,构造一个适配器就能完成模块衔接。

适配器模式的实现分为类与对象模式,类模式用继承,对象模式用组合,分别适用于 AdapteeTarget 结构相似与结构差异较大的场景,在任何情况下,组合模式都是灵活性最高的。

最后用一张图概括一下适配器模式的思维:

阅读全文
下载说明:
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.shuli.cc/?p=17792,转载请注明出处。
0

评论0

显示验证码
没有账号?注册  忘记密码?