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

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.kler.cn/a/611217.html

相关文章:

  • 技术迭代、流量困境与营销突破:基于开源AI大模型与S2B2C模式的创新路径研究
  • Rust从入门到精通之进阶篇:11.所有权系统详解
  • 第十一节 MATLAB关系运算符
  • 电动自行车/电动工具锂电池PCM方案--SH367003、SH367004、SH79F329
  • 深度分页优化思路
  • C++ 多线程简要讲解
  • Modbus RTU ---> Modbus TCP透传技术实现(Modbus透传、RS485透传、RTU透传)分站代码实现、协议转换器
  • Postman 下载文件指南:如何请求 Excel/PDF 文件?
  • 2025BAT大厂Java面试2000题精选(附答案+考点分析)
  • 人员进出新视界:视觉分析算法的力量
  • 淘宝获取商品sku详情API接口如何调用?
  • 前端学习笔记--CSS
  • vue vue3 走马灯Carousel
  • 如何 编译 px4
  • 物理环境与安全
  • 第十四届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组(部分题解)
  • 业务相关
  • 大模型开发框架LangChain GO
  • 5.Excel:从网上获取数据
  • macbook电脑如何清理键盘防止误触