精灵王


  • 首页

  • 文章归档

  • 所有分类

  • 关于我

  • 搜索
设计模式-行为型 设计模式-创建型 设计模式-结构型 设计 系统设计 设计模式之美 分布式 Redis 并发编程 个人成长 周志明的软件架构课 架构 单元测试 LeetCode 工具 位运算 读书笔记 操作系统 MySQL 异步编程 技术方案设计 集合 设计模式 三亚 游玩 转载 Linux 观察者模式 事件 Spring SpringCloud 实战 实战,SpringCloud 源码分析 线程池 同步 锁 线程 线程模型 动态代理 字节码 类加载 垃圾收集器 垃圾回收算法 对象创建 虚拟机内存 内存结构 Java

设计模式:结构型—适配器模式

发表于 2022-06-10 | 分类于 设计模式 | 0

定义

适配器模式(Adapter Design Pattern)将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。

适配器模式分为类结构型模式和对象结构型模式两种,其中,类适配器一般使用继承关系来实现,对象适配器使用组合关系来实现。

实现原理

对于适配器模式,我们可以用生活中常见的一个使用场景来解释,就是 USB 转接头充当适配器,把两种不兼容的接口,通过转接头变得可以一起工作。

适配器模式(Adapter)包含以下主要角色:

  1. 目标(Target)接口:当前系统业务所期待的接口,它可以是抽象类或接口。
  2. 适配者(Adaptee)类:它是被访问和适配的现存组件库中的组件接口。
  3. 适配器(Adapter)类:它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。

下面是两种不同的适配器代码实现方式,其中,ITarget表示要转化成的目标接口定义。Adaptee是一组不兼容 ITarget 接口定义的接口,Adapter 将Adaptee 转化成一组符合 ITarget 接口定义的接口。

类适配器模式

类适配器一般使用继承关系来实现,下面是类适配器模式的代码实现

// 类适配器: 基于继承
// 目标接口
public interface ITarget {
  void f1();
  void f2();
  void fc();
}
// 不兼容ITarget 的接口
public class Adaptee {
  public void fa() { //... }
  public void fb() { //... }
  public void fc() { //... }
}

// 适配器
public class Adapter extends Adaptee implements ITarget {
  public void f1() {
    super.fa();
  }
  
  public void f2() {
    //...重新实现f2()...
  }
  
  // 这里fc()不需要实现,直接继承自Adaptee,这是跟对象适配器最大的不同点
}

对象适配器

对象适配器使用组合关系来实现,下面是对象适配器的代码实现

// 对象适配器:基于组合
public interface ITarget {
  void f1();
  void f2();
  void fc();
}

public class Adaptee {
  public void fa() { //... }
  public void fb() { //... }
  public void fc() { //... }
}

public class Adapter implements ITarget {
  private Adaptee adaptee;
  
  public Adapter(Adaptee adaptee) {
    this.adaptee = adaptee;
  }
  
  public void f1() {
    adaptee.fa(); //委托给Adaptee
  }
  
  public void f2() {
    //...重新实现f2()...
  }
  
  public void fc() {
    adaptee.fc();
  }
}

选择哪一种

针对这两种实现方式,在实际的开发中,到底该如何选择使用哪一种呢?

判断的标准主要有两个,一个是 Adaptee 接口的个数,另一个是 Adaptee 和 ITarget 的契合程度。

  • 如果 Adaptee接口并不多,那两种实现方式都可以。
  • 如果 Adaptee接口很多,而且 Adaptee和 ITarget接口定义大部分都相同,那我们推荐使用类适配器,因为 Adapter复用父类 Adaptee的接口,比起对象适配器的实现方式,Adapter的代码量要少一些。
  • 如果 Adaptee 接口很多,而且 Adaptee和 ITarget接口定义大部分都不相同,那我们推荐使用对象适配器,因为组合结构相对于继承更加灵活。

应用场景

  1. 适配器模式可以看作一种“补偿模式”,用来封装有缺陷的接口设计。
    • 对外部系统提供的接口进行二次封装,抽象出更好的接口设计。
  2. 统一多个类的接口设计
    • 某个功能的实现依赖多个外部系统(或者说类),通过适配器模式,将它们的接口适配为统一的接口定义。
  3. 替换依赖的外部系统
    • 当我们把项目中依赖的一个外部系统替换为另一个外部系统的时候,利用适配器模式,可以减少对代码的改动。
  4. 兼容老版本接口
  5. 适配不同格式的数据
    1. Java 中的 Arrays.asList() 也可以看作一种数据适配器,将数组类型的数据转化为集合容器类型。

代理、桥接、装饰器、适配器 4 种设计模式的区别

这 4 种模式是比较常用的结构型设计模式。它们的代码结构非常相似。

笼统来说,它们都可以称为 Wrapper 模式,也就是通过 Wrapper 类二次封装原始类。

尽管代码结构相似,但这 4 种设计模式的用意完全不同,也就是说要解决的问题、应用场景不同,这也是它们的主要区别。

这里简单说一下它们之间的区别。

**代理模式:**代理模式在不改变原始类接口的条件下,为原始类定义一个代理类,主要目的是控制访问,而非加强功能,这是它跟装饰器模式最大的不同。

**桥接模式:**桥接模式的目的是将接口部分和实现部分分离,从而让它们可以较为容易、也相对独立地加以改变。

**装饰器模式:**装饰者模式在不改变原始类接口的情况下,对原始类功能进行增强,并且支持多个装饰器的嵌套使用。

**适配器模式:**适配器模式是一种事后的补救策略。适配器提供跟原始类不同的接口,而代理模式、装饰器模式提供的都是跟原始类相同的接口。

精 灵 王 wechat
👆🏼欢迎扫码关注微信公众号👆🏼
  • 本文作者: 精 灵 王
  • 本文链接: https://jinglingwang.cn/archives/adapterdesignpattern
  • 版权声明: 本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0 许可协议。转载请注明出处!
# 设计模式-行为型 # 设计模式-创建型 # 设计模式-结构型 # 设计 # 系统设计 # 设计模式之美 # 分布式 # Redis # 并发编程 # 个人成长 # 周志明的软件架构课 # 架构 # 单元测试 # LeetCode # 工具 # 位运算 # 读书笔记 # 操作系统 # MySQL # 异步编程 # 技术方案设计 # 集合 # 设计模式 # 三亚 # 游玩 # 转载 # Linux # 观察者模式 # 事件 # Spring # SpringCloud # 实战 # 实战,SpringCloud # 源码分析 # 线程池 # 同步 # 锁 # 线程 # 线程模型 # 动态代理 # 字节码 # 类加载 # 垃圾收集器 # 垃圾回收算法 # 对象创建 # 虚拟机内存 # 内存结构 # Java
设计模式:结构型—桥接模式
设计模式:结构型—门面模式
  • 文章目录
  • 站点概览
精 灵 王

精 灵 王

青春岁月,以此为伴

106 日志
14 分类
48 标签
RSS
Github E-mail
Creative Commons
Links
  • 添加友链说明
© 2023 精 灵 王
渝ICP备2020013371号
0%