重拾设计模式--适配器模式

news/2024/12/22 6:54:20/

文章目录

  • 适配器模式(Adapter Pattern)概述
  • 适配器模式UML图
  • 适配器模式的结构
    • 目标接口(Target):
    • 适配器(Adapter):
    • 被适配者(Adaptee):
  • 作用:
  • C++ 代码示例
  • C++示例代码2
  • 应用场景
    • 系统集成与接口兼容
    • 第三方库集成:
    • 旧代码适配新架构:
    • 软件模块交互与协作
    • 跨平台开发中的适配:

适配器模式(Adapter Pattern)概述

定义:
适配器模式是一种结构型设计模式它的主要作用是将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的类可以协同工作。就好像一个 “转换器”,把不匹配的接口进行适配,让它们能够相互对接使用。

适配器模式UML图

在这里插入图片描述

适配器模式的结构

目标接口(Target):

这是客户端所期望使用的接口,定义了客户端需要调用的方法集合。它代表了一种规范或者协议,客户端代码是基于这个接口来进行操作的。

适配器(Adapter):

它实现了目标接口,同时在内部持有一个被适配者的实例,并通过调用被适配者的相关方法来实现目标接口中定义的方法,以此来完成接口的转换工作,使得客户端可以通过目标接口来间接使用被适配者的功能。

被适配者(Adaptee):

它是已经存在的、具有特定功能但接口不符合要求的类或对象。其接口可能包含与目标接口相似但不完全相同的方法,或者方法名称、参数等方面存在差异。

作用:

解决接口不兼容问题:在软件开发过程中,经常会遇到需要使用一些现有的类,但这些类的接口与当前系统所期望的接口不一致的情况。适配器模式通过创建一个中间适配器类,对原有类的接口进行包装转换,使其符合新的使用要求,从而避免了对原有类进行大规模修改,保护了已有的代码资产。
提高代码的复用性:可以复用那些已经经过测试、功能完善但接口不符合要求的类,只需要添加适配器类来适配接口,就能让它们融入新的系统环境中继续发挥作用,减少了重复开发的工作量。
增强系统的灵活性和可扩展性:当系统需要接入新的外部组件或者更换底层实现时,如果存在接口不兼容的情况,通过编写适配器就能方便地实现对接,使得系统可以更容易地与不同的外部模块集成,应对各种变化。

C++ 代码示例

以下以一个简单的电源适配器的例子来展示适配器模式在代码中的应用。假设我们有一个手机充电器,它期望的输入电压是 5V,而我们现有的电源输出电压是 220V,需要一个适配器来将 220V 的电压转换为 5V 供手机充电器使用。

// 目标接口,代表手机充电器期望的输入接口
class ChargerTarget{
public:virtual void chargeWith5V() = 0;
};// 被适配者,代表现有的220V电源,有输出220V电压的方法
class PowerSource 
{
public:void output220V() {std::cout << "输出220V电压" << std::endl;}
};// 适配器类,将220V电源适配成手机充电器能用的5V电源
class VoltageAdapter : public ChargerTarget{
private:PowerSource* powerSource;
public:VoltageAdapter(PowerSource* source){powerSource = source;}void chargeWith5V() override{powerSource->output220V();std::cout << "经过适配器转换,输出5V电压用于充电" << std::endl;}
};int main() 
{PowerSource powerSource;VoltageAdapter adapter(&powerSource);ChargerTarget* charger = &adapter;charger->chargeWith5V();return 0;
}

在上述代码中:
ChargerTarget是目标接口,定义了chargeWith5V方法,代表手机充电器期望的输入接口规范,客户端希望调用这个接口来实现充电功能。
PowerSource是被适配者,它原本有自己的output220V方法,输出的是 220V 电压,不符合手机充电器直接使用的要求。
VoltageAdapter是适配器类,它实现了ChargerTarget接口,内部持有PowerSource对象的指针。在chargeWith5V方法中,先调用PowerSource的output220V方法获取 220V 电压,然后模拟进行转换,输出符合要求的 5V 电压,从而使得原本不匹配的电源和手机充电器能够协同工作,体现了适配器模式的基本原理和应用方式。
除了这种类适配器的形式(通过继承来实现适配),还有对象适配器(通过组合的方式,将被适配者对象作为适配器类的成员变量,代码结构稍有不同,但核心思想一致),可根据具体的应用场景和设计需求来选择合适的实现方式。

C++示例代码2

#include<iostream>
#include<string>
using namespace std;
//抽象球员类
class player
{protected:string m_name;
public:player(string str_name):m_name(str_name){}virtual void attack(){};virtual void defends(){};
};
//具体球员 前锋
class forwords:public player
{
public:forwords(string str_name):player(str_name){}void attack(){cout<<m_name<<"进攻"<<endl;}void defends(){cout<<m_name<<"防守"<<endl;}
};
//中锋
class center:public player
{
public:center(string str_name):player(str_name){}void attack(){cout<<m_name<<"进攻"<<endl;}void defends(){cout<<m_name<<"防守"<<endl;}
};class yaoming
{
private:string m_name;
public:yaoming(string str_name):m_name(str_name){}void attack_yaoming(){cout<<m_name<<"进攻"<<endl;}void defends_yaoming(){cout<<m_name<<"防守"<<endl;}
};class translate:public player
{
private:yaoming *s;
public:translate(string str_name):player(str_name){s = new yaoming("姚明");}void attack(){s->attack_yaoming();}void defends(){s->defends_yaoming();}};int main()
{player *s = new forwords("A");s->attack();player *s1 = new forwords("B");s1->attack();player *m_yaoming = new translate("姚明");m_yaoming->defends();m_yaoming->attack();return 0;
}

应用场景

系统集成与接口兼容

不同数据库的适配:当应用程序需要从一个数据库系统(如 MySQL)切换到另一个数据库系统(如 Oracle)时,由于数据库的 API 接口不同,就可以使用适配器模式。例如,原来的代码是基于 MySQL 的SELECT语句来查询数据,接口可能是mysql_query()函数。当切换到 Oracle 时,其查询接口是OCIStmtExecute()函数。可以创建一个适配器类,实现原来基于 MySQL 接口风格的函数,在内部将其转换为 Oracle 对应的函数调用,这样就可以在不大量修改上层业务逻辑代码的情况下完成数据库的替换。

第三方库集成:

在软件开发中,常常会使用第三方库来实现一些功能。如果第三方库的接口与项目中其他部分的接口不兼容,就可以使用适配器模式来整合。比如,一个图形绘制库的接口是接收坐标点的数组来绘制多边形,而项目中现有的图形数据存储格式是一系列的线段对象。这时可以创建一个适配器,将线段对象转换为坐标点数组的格式,使其能够被图形绘制库所使用。
旧系统改造与复用

旧代码适配新架构:

在对旧系统进行升级改造时,可能会引入新的架构或者设计模式。如果旧系统中的一些功能模块的接口不符合新架构的要求,就可以通过适配器模式来进行适配。例如,旧系统中有一个用户认证模块,它的接口是直接返回用户的基本信息字符串,而新架构要求通过一个对象来传递用户信息,包括用户名、密码、权限等多个属性。可以创建一个适配器类,将旧接口返回的字符串解析并封装成新架构所需要的用户信息对象,从而使旧的用户认证模块能够在新架构中继续使用。
硬件设备接口适配:在工业控制或者智能家居系统中,可能会存在新的控制系统与旧的硬件设备接口不匹配的情况。例如,新的智能控制系统期望通过网络协议接收和发送设备状态信息,而旧的传感器设备只有简单的串口通信接口并且数据格式不同。通过适配器模式,可以创建一个设备接口适配器,将串口通信的数据格式转换为网络协议的数据格式,并且处理通信方式的差异,使得旧设备能够在新的智能控制系统中正常工作。

软件模块交互与协作

不同模块间接口转换:在一个大型软件系统中,不同的模块可能是由不同的团队开发的,它们的接口设计可能没有考虑到相互之间的协作。当需要将这些模块集成在一起时,就可能会出现接口不兼容的问题。例如,一个数据处理模块输出的数据结构是链表形式,而另一个数据分析模块期望的数据结构是数组形式。可以通过适配器模式,创建一个数据结构适配器,将链表数据转换为数组数据,使得两个模块能够顺利地进行数据交互。

跨平台开发中的适配:

在跨平台应用开发中,不同的操作系统(如 Windows、Linux、macOS)提供的 API 接口有所不同。例如,在 Windows 系统中,创建窗口的函数是CreateWindow(),而在 Linux 系统下可能是通过XCreateWindow()函数(基于 X Window 系统)。为了使应用程序能够在不同的操作系统上运行,可以使用适配器模式。创建一个窗口创建适配器类,在不同的操作系统下实现不同的窗口创建函数,但是对外提供统一的窗口创建接口,这样就可以在跨平台开发中方便地处理操作系统接口的差异。


http://www.ppmy.cn/news/1557131.html

相关文章

课上测试:商用密码标准实现

文章目录 完成下面任务&#xff08;29分&#xff09;1 在 Ubuntu 或 openEuler 中完成任务&#xff08;推荐openEuler&#xff09;2 简述 GM/T0009 4种数据转换的功能&#xff0c;根据你的理解&#xff0c;每种转换功能给出至少一个例子 &#xff08;8分&#xff09;3 参考课程…

EGO Swarm翻译

目录 摘要 Ⅰ 介绍 Ⅱ 相关工作 A . 单四旋翼局部规划 B . 拓扑规划 C. 分布式无人机集群 Ⅲ 基于梯度的局部规划隐式拓扑轨迹生成 A.无需ESDF梯度的局部路径规划 B.隐式拓扑轨迹生成 Ⅳ 无人机集群导航 A 机间避碰 B. 定位漂移补偿 C. 从深度图像中去除agent Ⅴ …

适用于.net的操作excel的库

目录 目录 知识点概要 知识点具体说明(使用步骤、解释) 使用场景及示例 1. EPPlus 2. NPOI 3. ClosedXml 4. SpreadsheetLight 5.ExcelDataReader 开源库 6. ExcelDataWriter 总结 知识点概要 使用Excel来导入和导出数据&#xff0c;在日常工作中使用频率是相当高的&…

3D造型软件solvespace在windows下的编译

3D造型软件solvespace在windows下的编译 在逛开源社区的时候发现了几款开源CAD建模软件&#xff0c;一直囿于没有合适的建模软件&#xff0c;虽然了解了很多的模拟分析软件&#xff0c;却不能使之成为整体的解决方案&#xff0c;从而无法产生价值。opencascad之流虽然可行&…

FPGA设计-使用 lspci 和 setpci 调试xilinx的PCIe 问题

目录 简介 lspci lspci-TV lspci-vvv 注意事项 lspci -vs lspci -vvvs 设置pci 识别setpci中的寄存器 setpci -s 00:01.0 d0.b42 简介 lspci 和 setpci 命令在 Linux 发行版中本身可用。该命令具有各种级别的输出&#xff0c;并提供非常有用的时间点查看 PCI 总线…

Mac配置 Node镜像源的时候报错解决办法

在Mac电脑中配置国内镜像源的时候报错,提示权限问题,无法写入配置文件。本文提供解决方法,青测有效。 一、原因分析 遇到的错误是由于 .npm 目录下的文件被 root 用户所拥有,导致当前用户无法写入相关配置文件。 二、解决办法 在终端输入以下命令,输入管理员密码即可。 su…

基于Spring Boot的数码产品抢购系统

一、系统背景与目的 随着电子商务的快速发展&#xff0c;数码产品在线销售已成为主流趋势。然而&#xff0c;传统的数码产品销售方式存在抢购过程繁琐、库存管理混乱、用户体验不佳等问题。为了解决这些问题&#xff0c;基于Spring Boot的数码产品抢购系统应运而生。该系统旨在…

【Verilog】实验八 有限状态机设计

一、实验目的 1. 掌握有限状态机原理和设计方法。 2. 掌握ModelSim和VIVADO工具软件。 3. 掌握基本的测试代码编写和FPGA开发板使用方法。 二、实验环境 1. 装有ModelSim和VIVADO的计算机。 2. Sword实验系统。 三、实验原理 有限状态机是时序电路的通用模型&#xff0…