C语言-适配器模式详解与实践

文章目录

  • C语言适配器模式详解与实践
    • 1. 什么是适配器模式?
    • 2. 为什么需要适配器模式?
    • 3. 实际应用场景
    • 4. 代码实现
      • 4.1 UML 关系图
      • 4.2 头文件 (sensor_adapter.h)
      • 4.3 实现文件 (sensor_adapter.c)
      • 4.4 使用示例 (main.c)
    • 5. 代码分析
      • 5.1 关键设计点
      • 5.2 实现特点
    • 6. 编译和运行
    • 7. 注意事项
    • 8. 改进建议
    • 9. 总结
    • 参考资料

C语言适配器模式详解与实践

1. 什么是适配器模式?

适配器模式是一种结构型设计模式,它允许将一个类的接口转换成客户端所期望的另一个接口。适配器让原本由于接口不兼容而不能一起工作的类可以协同工作。

2. 为什么需要适配器模式?

  • 兼容不同接口
  • 复用现有代码
  • 统一接口规范
  • 平滑过渡旧系统
  • 整合第三方库

3. 实际应用场景

  • 传感器数据适配
  • 通信协议转换
  • 接口版本兼容
  • 数据格式转换
  • 驱动程序适配

4. 代码实现

4.1 UML 关系图

NewInterface
+process_data()
OldSystem
+old_process()
Adapter
-old_system
+process_data()

4.2 头文件 (sensor_adapter.h)

#ifndef SENSOR_ADAPTER_H
#define SENSOR_ADAPTER_H#include <stdint.h>// 新接口定义的数据结构
typedef struct {float temperature;float humidity;float pressure;uint32_t timestamp;
} SensorData;// 旧系统的数据结构
typedef struct {int16_t temp_raw;      // 原始温度数据int16_t humi_raw;      // 原始湿度数据int16_t pres_raw;      // 原始气压数据uint32_t time;         // 时间戳
} LegacySensorData;// 新接口
typedef struct {void (*process_data)(const SensorData* data);
} NewInterface;// 旧系统接口
typedef struct {void (*old_process)(const LegacySensorData* data);
} OldSystem;// 适配器
typedef struct {NewInterface interface;OldSystem* old_system;
} SensorAdapter;// 创建适配器
SensorAdapter* create_sensor_adapter(OldSystem* old_system);// 销毁适配器
void destroy_sensor_adapter(SensorAdapter* adapter);// 数据转换函数
SensorData convert_sensor_data(const LegacySensorData* old_data);#endif // SENSOR_ADAPTER_H

4.3 实现文件 (sensor_adapter.c)

#include "sensor_adapter.h"
#include <stdio.h>
#include <stdlib.h>// 数据转换实现
SensorData convert_sensor_data(const LegacySensorData* old_data) {SensorData new_data;// 温度转换 (原始数据除以100得到实际温度)new_data.temperature = old_data->temp_raw / 100.0f;// 湿度转换 (原始数据除以100得到实际湿度)new_data.humidity = old_data->humi_raw / 100.0f;// 气压转换 (原始数据除以10得到实际气压)new_data.pressure = old_data->pres_raw / 10.0f;// 时间戳保持不变new_data.timestamp = old_data->time;return new_data;
}// 适配器的处理函数
static void adapter_process_data(const SensorData* data) {// 将新格式数据转换回旧格式LegacySensorData old_data = {.temp_raw = (int16_t)(data->temperature * 100),.humi_raw = (int16_t)(data->humidity * 100),.pres_raw = (int16_t)(data->pressure * 10),.time = data->timestamp};// 获取适配器实例SensorAdapter* adapter = (SensorAdapter*)((char*)data - offsetof(SensorAdapter, interface));// 调用旧系统的处理函数adapter->old_system->old_process(&old_data);
}// 创建适配器
SensorAdapter* create_sensor_adapter(OldSystem* old_system) {SensorAdapter* adapter = (SensorAdapter*)malloc(sizeof(SensorAdapter));adapter->interface.process_data = adapter_process_data;adapter->old_system = old_system;return adapter;
}// 销毁适配器
void destroy_sensor_adapter(SensorAdapter* adapter) {free(adapter);
}

4.4 使用示例 (main.c)

#include "sensor_adapter.h"
#include <stdio.h>// 旧系统的处理函数
static void legacy_process(const LegacySensorData* data) {printf("旧系统处理数据:\n");printf("原始温度: %d (0.01°C)\n", data->temp_raw);printf("原始湿度: %d (0.01%%)\n", data->humi_raw);printf("原始气压: %d (0.1hPa)\n", data->pres_raw);printf("时间戳: %u\n", data->time);
}// 新系统的处理函数
static void new_process(const SensorData* data) {printf("新系统处理数据:\n");printf("温度: %.2f°C\n", data->temperature);printf("湿度: %.2f%%\n", data->humidity);printf("气压: %.1fhPa\n", data->pressure);printf("时间戳: %u\n", data->timestamp);
}int main() {// 创建旧系统OldSystem old_system = {legacy_process};// 创建适配器SensorAdapter* adapter = create_sensor_adapter(&old_system);// 测试数据LegacySensorData legacy_data = {.temp_raw = 2550,    // 25.50°C.humi_raw = 6000,    // 60.00%.pres_raw = 10150,   // 1015.0hPa.time = 1234567890};printf("=== 测试1:旧数据转换为新格式 ===\n");SensorData new_data = convert_sensor_data(&legacy_data);new_process(&new_data);printf("\n=== 测试2:新接口适配到旧系统 ===\n");adapter->interface.process_data(&new_data);// 清理资源destroy_sensor_adapter(adapter);return 0;
}

5. 代码分析

5.1 关键设计点

  1. 接口转换机制
  2. 数据格式转换
  3. 适配器封装
  4. 向后兼容性

5.2 实现特点

  1. 函数指针实现接口
  2. 数据结构转换
  3. 内存管理安全
  4. 使用简单直观

6. 编译和运行

gcc -c sensor_adapter.c -o sensor_adapter.o
gcc -c main.c -o main.o
gcc sensor_adapter.o main.o -o adapter_demo

7. 注意事项

  1. 数据转换精度
  2. 内存管理
  3. 错误处理
  4. 性能开销

8. 改进建议

  1. 添加错误检查
  2. 支持批量数据
  3. 优化转换效率
  4. 添加数据验证

9. 总结

适配器模式通过转换接口,使得原本不兼容的系统能够协同工作。这种模式特别适合系统升级或整合第三方库的场景。

参考资料

  1. 《设计模式:可复用面向对象软件的基础》
  2. 《C语言程序设计》
  3. 《嵌入式系统设计》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/74275.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Rust函数、条件语句、循环

文章目录 函数**语句与表达式**条件语句循环 函数 Rust的函数基本形式是这样的 fn a_func(a: i32) -> i32 {}函数名是蛇形风格&#xff0c;rust不在意函数的声明顺序&#xff0c;只需要有声明即可 函数参数必须声明参数名称和类型 语句与表达式 这是rust非常重要的基础…

maptalks图层交互 - 模拟 Tooltip

maptalks图层交互 - 模拟 Tooltip 图层交互-模拟tooltip官方文档 <!DOCTYPE html> <html><meta charsetUTF-8 /><meta nameviewport contentwidthdevice-width, initial-scale1 /><title>图层交互 - 模拟 Tooltip</title><style typet…

好吧好吧,看一下达梦的模式与用户的关系

单凭个人感觉&#xff0c;模式在达梦中属于逻辑对象合集&#xff0c;回头再看资料 应该是一个用户可以对应多个模式 问题来了&#xff0c;模式的ID和用户的ID一样吗&#xff1f; 不一样 SELECT USER_ID,USERNAME FROM DBA_USERS WHERE USERNAMETEST1; SELECT ID AS SCHID, NA…

python socket模块学习记录

python黑马程序员 通过python内置socket模块&#xff0c;在电脑本地开发一个服务器&#xff0c;一个客户端&#xff0c;连接后进行连续的聊天。服务器和客户端均可输入exit&#xff0c;主动退出连接。 服务器开发.py import socket# 创建Socket对象 socket_server socket.s…

7-2 sdut-C语言实验-逆序建立链表

7-2 sdut-C语言实验-逆序建立链表 分数 20 全屏浏览 切换布局 作者 马新娟 单位 山东理工大学 输入整数个数N&#xff0c;再输入N个整数&#xff0c;按照这些整数输入的相反顺序建立单链表&#xff0c;并依次遍历输出单链表的数据。 输入格式: 第一行输入整数N;&#xff…

针对永磁电机(PMM)的d轴和q轴电流,考虑交叉耦合补偿,设计P1控制器并推导出相应的传递函数

电流控制回路:针对永磁电机(PMM)的d轴和q轴电流&#xff0c;考虑交叉耦合补偿&#xff0c;设计P1控制器并推导出相应的传递函数。 1. 永磁电机&#xff08;PMM&#xff09;的数学模型 在同步旋转坐标系&#xff08; d − q d - q d−q 坐标系&#xff09;下&#xff0c;永磁同…

ROS多机通信(四)——Ubuntu 网卡 Mesh 模式配置指南

引言 使用Ad-hoc加路由协议和直接Mesh模式配置网卡实现的网络结构是一样的&#xff0c;主要是看应用选择&#xff0c; Ad-Hoc模式 B.A.T.M.A.N. / OLSR 优点&#xff1a;灵活性高&#xff0c;适合移动性强或需要优化的复杂网络。 缺点&#xff1a;配置复杂&#xff0c;需手动…

chap1:统计学习方法概论

第1章 统计学习方法概论 文章目录 第1章 统计学习方法概论前言章节目录导读 实现统计学习方法的步骤统计学习分类基本分类监督学习无监督学习强化学习 按模型分类概率模型与非概率模型 按算法分类按技巧分类贝叶斯学习核方法 统计学习方法三要素模型模型是什么? 策略损失函数与…

爬虫案例-爬取某站视频

文章目录 1、下载FFmpeg2、爬取代码3、效果图 1、下载FFmpeg FFmpeg是一套可以用来记录、转换数字音频、视频&#xff0c;并能将其转化为流的开源计算机程序。 点击下载: ffmpeg 安装并配置 FFmpeg 步骤&#xff1a; 1.下载 FFmpeg&#xff1a; 2.访问 FFmpeg 官网。 3.选择 Wi…

车载以太网网络测试-22【传输层-DOIP协议-5】

目录 1 摘要2 DoIP时间参数2.1 ISO 13400定义的时间参数2.2 参数示例 3 DoIP节点内部状态机4 UDSonIP概述5 总结 1 摘要 本文继续对DOIP协议进行介绍&#xff0c;主要是DOIP相关的时间参数、时间参数定义以及流程示例。推荐大家对上文专题进行回顾&#xff0c;有利于系统性学习…

(论文总结)思维链激发LLM推理能力

研究背景&动机 背景:扩大模型规模已被证实具有提升模型性能和模型效率的功效&#xff0c;但是LLM对于完成推理、算术任务仍有较大不足。 动机:从之前的应用和研究中得知&#xff0c;可以用生成自然语言解释、使用神经符号等形式语言的方法来提高大模型的算术推理能力&…

前后端开发概述:架构、技术栈与未来趋势

一、前后端开发的基本概念 1.1 什么是前后端开发&#xff1f; 前后端开发是 Web 开发的两个核心部分&#xff0c;各自承担不同的职责&#xff1a; 前端&#xff08;Frontend&#xff09; 负责网页的用户界面&#xff08;UI&#xff09;和用户体验&#xff08;UX&#xff09;…

anythingLLM结合searXNG实现联网搜索

1、docker-compose 部署searXNG GitHub - searxng/searxng-docker: The docker-compose files for setting up a SearXNG instance with docker. cd /usr/local git clone https://github.com/searxng/searxng-docker.git cd searxng-docker 2、修改 .env文件 # By default…

人形机器人科普

人形机器人&#xff08;Humanoid Robot&#xff09;是一种模仿人类外形和行为的机器人&#xff0c;通常具有头部、躯干、双臂和双腿等结构。它们的设计目标是与人类环境无缝交互&#xff0c;执行复杂的任务&#xff0c;甚至在某些领域替代人类工作。 1. 人形机器人的定义与特点…

【CICD】Ansible知识库

一、主机清单配置 1. 配置文件路径 默认路径 /etc/ansible/hosts 这是 Ansible 的全局默认库存文件路径&#xff0c;但许多用户可能不会直接使用它。项目目录或自定义路径 用户通常会为不同项目创建独立的库存文件&#xff0c;例如&#xff1a; 当前目录下的 hosts、inventor…

ArkUI-List组件

列表是一个复杂的容器&#xff0c;当列表项达到一定数量&#xff0c;使得列表内容超出其范围的时候&#xff0c;就会自动变为可以滚动。列表适合用来展现同类数据类型。 List的基本使用方法 List组件的构建声明是这个样子的 List(value?: {space?:number | string, initial…

Ubuntu实时读取音乐软件的音频流

文章目录 一. 前言二. 开发环境三. 具体操作四. 实际效果 一. 前言 起因是这样的&#xff0c;我需要在Ubuntu中&#xff0c;实时读取正在播放音乐的音频流&#xff0c;然后对音频进行相关的处理。本来打算使用的PipewireHelvum的方式实现&#xff0c;好处是可以直接利用Helvum…

【yolo】YOLO训练参数输入之模型输入尺寸

模型输入尺寸是YOLO训练和推理过程中非常重要的参数之一。YOLO要求输入图像的尺寸是固定的&#xff0c;通常为正方形&#xff08;如416416、640640等&#xff09;。这个尺寸直接影响模型的性能和速度。以下是对模型输入尺寸的详细介绍&#xff1a; 1. 模型输入尺寸的作用 统一…

【TI MSPM0】Timer学习

一、计数器 加法计数器&#xff1a;每进入一个脉冲&#xff0c;就加一减法计算器&#xff1a;每进入一个脉冲&#xff0c;就减一 当计数器减到0&#xff0c;触发中断 1.最短计时时间 当时钟周期为1khz时&#xff0c;最短计时时间为1ms&#xff0c;最长计时时间为65535ms 当时…

从WebRTC到嵌入式:EasyRTC如何借助大模型提升音视频通信体验

随着人工智能技术的快速发展&#xff0c;WebRTC与大模型的结合正在为音视频通信领域带来革命性的变革。WebRTC作为一种开源实时通信技术&#xff0c;以其低延迟、跨平台兼容性和强大的音视频处理能力&#xff0c;成为智能硬件和物联网设备的重要技术支撑。 而EasyRTC作为基于W…