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

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. 《嵌入式系统设计》

相关文章:

  • Pydantic字段级校验:解锁@validator的12种应用
  • OpenFOAM中snappyHexMesh网格工具如何使用,有哪些使用技巧
  • 拉取镜像,推送到阿里云镜像仓库
  • WX小程序
  • mac丝滑安装Windows操作系统【丝滑简单免费】
  • 微前端qiankun框架的使用
  • 【Linux】信号:信号保存和处理
  • AI比人脑更强,因为被植入思维模型【18】万物系统思维模型
  • 如何通过less在vue2中达到切换皮肤的目的
  • Java实习生面试题(2025.3.23 be)
  • nacos未经授权创建用户漏洞
  • Word限定仅搜索中文或英文引号
  • DFS深搜
  • 算法基础——栈
  • 银河麒麟桌面版包管理器(二)
  • mysql学习-B+树相关问题
  • leetcode 108 将有序数组转换为二叉搜索树
  • HQChart使用教程46-K线图如何对接第3方数据42-DRAWTEXT_LINE数据结构
  • 20届智能车赛规则
  • python环境出现出现 pip: command not found 错误
  • 获派驻6年后,中国驻厄瓜多尔大使陈国友即将离任
  • 杨文庄当选中国人口学会会长,曾任国家卫健委人口家庭司司长
  • 南方降水频繁暴雨连连,北方高温再起或现40°C酷热天气
  • 六连板成飞集成:航空零部件业务收入占比为1.74%,市场环境没有重大调整
  • 泽连斯基启程前往土耳其
  • 德国总理默茨发表首份政府声明:将提升国防能力,全力发展经济