当前位置: 首页 > news >正文

设计模式十四:适配器模式(Adapter Pattern)

适配器模式(Adapter Pattern)是一种结构型设计模式,用于将一个类的接口转换成客户端期望的另一个接口,使原本不兼容的类可以一起工作。

适配器模式的类型

  1. 类适配器(通过多重继承实现)

  2. 对象适配器(通过组合实现,更常用)

示例代码

1. 对象适配器示例(推荐方式)

#include <iostream>// 目标接口(客户端期望的接口)
class Target {
public:virtual ~Target() = default;virtual void request() const {std::cout << "Target: 标准请求\n";}
};// 需要适配的类(不兼容的接口)
class Adaptee {
public:void specificRequest() const {std::cout << "Adaptee: 特殊请求\n";}
};// 适配器类(将Adaptee接口转换为Target接口)
class Adapter : public Target {
private:Adaptee* adaptee;
public:Adapter(Adaptee* a) : adaptee(a) {}void request() const override {std::cout << "Adapter: 转换请求\n";adaptee->specificRequest();}
};int main() {Adaptee* adaptee = new Adaptee();Target* target = new Adapter(adaptee);target->request();  // 客户端调用统一的接口delete target;delete adaptee;return 0;
}

2. 类适配器示例(需要多重继承)

#include <iostream>// 目标接口
class Target {
public:virtual ~Target() = default;virtual void request() const {std::cout << "Target: 标准请求\n";}
};// 需要适配的类
class Adaptee {
public:void specificRequest() const {std::cout << "Adaptee: 特殊请求\n";}
};// 类适配器(通过多重继承)
class Adapter : public Target, private Adaptee {
public:void request() const override {std::cout << "Adapter: 转换请求\n";specificRequest();  // 调用Adaptee的方法}
};int main() {Target* target = new Adapter();target->request();delete target;return 0;
}

 UML结构

 

要点总结

1、Adapter模式主要应用于“希望复用一些现存的类,但是接口又与复用环境要求不一致的情况”,在遗留代码复用、类库迁移等方面非常有用。
2、GoF 23 定义了两种Adapter模式的实现结构:对象适配器和类适配器。但类适配器采用“多继承”的实现方式,一般不推荐使用。对象适配器采用“对象组合”的方式,更符合松耦合精神。
3、Adapter模式可以实现的非常灵活,不必拘泥于Gof23中定义的两种结构。例如,完全可以将Adapter模式中的“现存对象”作为新的接口方法参数,来达到适配的目的。 

适配器模式的应用场景

  1. 需要使用现有类,但其接口与你的代码不兼容时

  2. 想复用一些现有的子类,但这些子类缺少一些公共功能

  3. 需要统一多个不同类的接口

优点

  • 单一职责原则:可以将接口转换代码与业务逻辑分离

  • 开闭原则:可以在不修改现有代码的情况下引入新的适配器

缺点

  • 代码整体复杂度增加:需要新增一系列接口和类

 

适配器模式在C++标准库中也有应用,例如stackqueue就是通过适配其他容器(如deque)实现的。 

http://www.lryc.cn/news/604762.html

相关文章:

  • Linux ps -ef 命令解析
  • 基于成像空间转录组技术的肿瘤亚克隆CNV原位推断方法
  • composer 常用命令
  • 智慧城市SaaS平台|市政公用管理系统
  • 从单机到分布式:Redis如何成为架构升级的胜负手
  • 串口接收数据包(协议带帧头帧尾)的编程实现方法:1、数据包格式定义结构体2、使用队列进行数据接收、校验解包
  • 三十二、【Linux网站服务器】搭建httpd服务器演示虚拟主机配置、网页重定向功能
  • uni-app webview 的message无法触发的解决方案
  • MacTex+Vscode数学建模排版
  • 字节跳动“扣子”(Coze)开源:AI智能体生态的技术革命
  • AI Compass前沿速览:可灵创意工坊、字节Coze StudioCoze Loop、通义万相2.2 、智谱GLM-4.5、腾讯混元3D世界模型开源
  • 添加捕捉吸附标识(使用QT+OpenGL开发三维CAD)
  • 【翻译】Label Studio——开源标注工具README.md
  • 2025年DDoS攻防战:六层防护体系构建业务“数字免疫”
  • ADA4622-2ARMZ-R7 ADI双通道精密运算放大器 ±0.25μV超低失调+0.1μV/°C温漂
  • K8s 备份与恢复利器:Velero 实战指南
  • click和touch事件触发顺序 糊里糊涂解决的奇怪bug
  • VUE -- 基础知识讲解(三)
  • 前端安全防护:XSS、CSRF与SQL注入漏洞深度解析与防御
  • 50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | 3dBackgroundBoxes(3D背景盒子组件)
  • 前端兼容性问题全面解决方案
  • Vue2-封装一个看起来像左右分布表格的表单组件
  • JetBrains Annotations:从入门到落地,彻底告别 NullPointerException
  • 2025年GEO服务商有哪些?——从技术到服务的专业分析
  • 2507C++,介绍名字对象
  • Java Stream核心:ReferencePipeline解析
  • 【WPS】邮件合并教程\Excel批量写入数据进Word模板
  • 滚珠导轨在电子制造中的流畅性优势
  • 新零售“实—虚—合”逻辑下的技术赋能与模式革新:基于开源AI大模型、AI智能名片与S2B2C商城小程序源码的研究
  • 洛谷 P11230:[CSP-J 2024 T4] 接龙 ← 图论+动态规划