适配器模式

义项:软件设计模式
适配器模式

适配器模式(Adapter Pattern)是一种结构型设计模式,它把一个类的接口转换成客户端期待的另一种接口,使原本因接口不兼容而无法协作的类能够一起工作。该模式在二十世纪九十年代由“四人帮”归纳进面向对象设计模式的经典体系中,常用于复用现有组件、对接第三方类库以及改造正在运行的系统,而不必修改原有代码。

目录
  1. 定义
  2. 原理
  3. 发展历程
  4. 应用
  5. 局限
  6. 参见

定义

适配器模式是指把一个类的接口变换成客户端所期望的另一种接口,让原本因接口不匹配而无法在一起工作的两个类可以协同工作[1]。它的出发点是兼容性,而不是创造新功能:被复用的组件本身往往已经存在并且可用,问题只在于它的调用方式与当前系统的规范对不上。

该模式通常涉及4个角色,即客户端、目标接口、适配者和适配器。目标是客户端希望使用的接口,适配者是需要被转换的现存组件,适配器则是二者之间的转换器,客户端只依赖目标接口,通过它间接调用适配者的能力。按照实现手段的不同,适配器模式可分为类适配器与对象适配器2种形态[2]。

原理

适配器的核心是一层接口转换代码。客户端按目标接口发起调用,适配器接收到调用后,把方法名、参数或数据结构翻译成适配者能够接受的形式,再转交给适配者执行,最后把结果转换回目标接口约定的形式返回。整个过程中,适配者的源码不需要改动,客户端也不需要知道适配者的存在[3]。

类适配器依靠继承实现。适配器类同时继承适配者并实现目标接口,因此继承了适配者的全部方法,把目标接口中的方法改写为对适配者方法的调用。C++等支持多重继承的语言可以直接让适配器类同时继承目标与适配者;Java不支持多继承,只能以继承适配者、实现目标接口的方式变通。

对象适配器依靠组合实现。适配器类实现目标接口,同时在内部持有一个适配者对象的引用,把目标方法委托给该对象。由于不涉及继承,一个适配器可以对适配者本身及其子类一并生效,组合关系也比继承更加灵活,因此在多数场景下被优先采用[2]。


classDiagram

class Client

class Target {

<<interface>>

+request()

}

class Adapter {

-adaptee: Adaptee

+request()

}

class Adaptee {

+specificRequest()

}

Client --> Target

Target <|.. Adapter

Adapter --> Adaptee

适配器模式还有一种扩展形态,即双向适配器。双向适配器同时持有目标方与适配者方,既能把适配者接口转成目标接口,也能反向把目标接口转成适配者接口,用于两个方向都需要互调的场景[4]。

发展历程

适配器模式作为成文的模式条目,最早出现在1994年出版的《设计模式:可复用面向对象软件的基础》一书中。该书的4位作者埃里希·伽玛、理查德·赫尔姆、拉尔夫·约翰逊和约翰·弗利赛德斯被合称为“四人帮”(Gang of Four,GoF),书中收录的23种设计模式也因此被称为“四人帮设计模式”[5]。

在该书的分类框架中,设计模式按目的分为创建型、结构型和行为型3类,适配器模式被归入结构型。结构型模式共有7种,除适配置模式外还包括桥接、装饰、组合、外观、享元和代理,它们共同关注类和对象如何组合成更大的结构。此后的实践普遍把适配器看作一种补救性手段:它主要出现于系统后期扩展或改造阶段,而不是在全新系统的详细设计中主动引入。

应用

遗留系统改造是适配器模式的典型用途。当已有组件满足新的业务需求,但接口与现行规范不一致,而重写组件的代价又较高时,可以增加一个适配器把旧接口包装成新接口,从而在不改动原有代码的前提下复用这部分能力。以文档处理为例,系统中已有能处理某一种格式文档的组件,若要让其同时支持另一种格式,可以针对格式差异编写适配器,把新格式的调用转换为旧组件能够执行的操作。

对接第三方类库时也常引入适配器。应用与外部类库之间加一层适配器,应用只依赖自身定义的目标接口,类库被隔离在适配器之后;日后更换类库,只需替换适配器实现,应用代码基本不受影响[3]。Dart、Flutter 等语言与框架的资料中,同样把这种包装第三方接口的做法列为适配器模式的常见使用场景[2]。

在一些框架内部也能看到该模式的结构。Spring MVC对请求的处理依赖适配器机制:控制器(Controller)有多种类型,各自的处理方法并不相同,框架通过统一的处理器适配器接口调用不同类型控制器的方法,避免在分发逻辑中逐一判断控制器类型。Android 的列表控件同样采用类似思路,把多种形式的条目描述转换为列表控件能够识别的视图对象[2]。

局限

适配器模式增加了系统中的间接层次。调用方看到的是目标接口,实际执行的是被包装的适配者,代码阅读时需要跨过适配器才能追溯到真实实现;适配器用得过多,调用链会变得零散,整体结构不易把握。因此在该模式并不必要时,直接重构系统往往比叠加适配器更可取。

2种实现形态各有约束。类适配器依赖继承,在只支持单继承的语言中一次只能适配一个适配者,并且无法把一个适配者及其子类一并适配到目标接口[6]。对象适配器的适配范围更宽,但若要替换适配者已有的某个方法就较为麻烦,通常得先为适配者建立子类并重写相应方法,再让适配器引用这个子类[6]。

适配器只改变调用的形式,并不改变被适配组件本身的行为和能力边界。接口语义差异过大、或者双方在数据含义上并不对应时,一层转换无法弥补,此时需要的是重新设计接口或重构原有组件,而不是继续增加适配层。

参见

  • 设计模式 —— 适配器模式所属的面向对象软件设计经验体系。

  • 装饰器模式 —— 同样以包装对象的方式扩展功能,但不改变接口。

  • 代理模式 —— 在客户端与目标之间加一层间接对象,侧重控制访问。

  • 外观模式 —— 为子系统提供统一的高层接口,与适配器一样起接口统一作用。

  • 桥接模式 —— 分离抽象与实现,使两者可独立变化。

参考资料

  1. 从零开始学设计模式(六)—适配器模式(Adapter Pattern) [引用日期2026-10-29]
  2. 灵动的适配器模式 [引用日期2026-10-29]
  3. --- [引用日期2026-10-29]
  4. 适配器模式(Adapter) [引用日期2026-10-29]
  5. 设计模式:可复用面向对象软件的基础 [引用日期2026-10-29]
  6. 从零开始学设计模式(六):适配器模式(Adapter Pattern) [引用日期2026-10-29]
词条评价
词条统计

浏览次数:2 次

阅读量:0 次 · 阅读完成量:0 次

最近更新:2026-10-28T18:19:47Z

历史版本

本条目引用的词条
Java Spring MVC 设计模式 装饰器模式 代理模式 外观模式 桥接模式