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

C语言-访问者模式详解与实践

C语言访问者模式详解与实践 - 传感器数据处理系统

1. 什么是访问者模式?

在嵌入式系统中,我们经常需要对不同传感器的数据进行多种处理,如数据校准、过滤、存储等。访问者模式允许我们在不修改传感器代码的情况下,添加新的数据处理方法。

2. 为什么需要访问者模式?

  • 分离数据采集和处理逻辑
  • 便于添加新的数据处理方法
  • 避免修改现有传感器代码
  • 便于数据处理的复用
  • 结构清晰,易于维护

3. 实际应用场景

  • 多传感器数据处理
  • 数据校准和滤波
  • 传感器状态监控
  • 数据记录和分析
  • 故障诊断系统

4. 代码实现

4.1 头文件 (sensor_visitor.h)

#ifndef SENSOR_VISITOR_H
#define SENSOR_VISITOR_H

#include <stdint.h>

// 传感器类型
typedef enum {
    TEMP_SENSOR,
    HUMIDITY_SENSOR
} SensorType;

// 传感器数据结构
typedef struct {
    uint16_t raw_data;    // 原始数据
    uint32_t timestamp;   // 时间戳
    SensorType type;      // 传感器类型
} SensorData;

// 温度传感器
typedef struct {
    SensorData data;
    float offset;         // 温度补偿值
} TempSensor;

// 湿度传感器
typedef struct {
    SensorData data;
    uint8_t threshold;    // 湿度阈值
} HumiditySensor;

// 访问者接口
typedef struct {
    void (*visit_temp)(void* self, TempSensor* sensor);
    void (*visit_humidity)(void* self, HumiditySensor* sensor);
    void* context;        // 访问者上下文
} SensorVisitor;

// 传感器操作接口
void accept_visitor(void* sensor, SensorType type, SensorVisitor* visitor);

// 创建传感器
TempSensor* create_temp_sensor(uint16_t raw_data, float offset);
HumiditySensor* create_humidity_sensor(uint16_t raw_data, uint8_t threshold);

// 创建访问者
SensorVisitor* create_calibration_visitor(void);   // 校准访问者
SensorVisitor* create_filter_visitor(void);        // 滤波访问者
SensorVisitor* create_alarm_visitor(void);         // 报警访问者

// 销毁函数
void destroy_sensor(void* sensor);
void destroy_visitor(SensorVisitor* visitor);

#endif // SENSOR_VISITOR_H

4.2 实现文件 (sensor_visitor.c)

#include "sensor_visitor.h"
#include <stdio.h>
#include <stdlib.h>

// 传感器创建函数
TempSensor* create_temp_sensor(uint16_t raw_data, float offset) {
    TempSensor* sensor = (TempSensor*)malloc(sizeof(TempSensor));
    sensor->data.raw_data = raw_data;
    sensor->data.timestamp = 0;  // 实际应用中需要获取真实时间戳
    sensor->data.type = TEMP_SENSOR;
    sensor->offset = offset;
    return sensor;
}

HumiditySensor* create_humidity_sensor(uint16_t raw_data, uint8_t threshold) {
    HumiditySensor* sensor = (HumiditySensor*)malloc(sizeof(HumiditySensor));
    sensor->data.raw_data = raw_data;
    sensor->data.timestamp = 0;
    sensor->data.type = HUMIDITY_SENSOR;
    sensor->threshold = threshold;
    return sensor;
}

// 校准访问者实现
static void calibrate_temp(void* self, TempSensor* sensor) {
    float real_temp = sensor->data.raw_data * 0.1f + sensor->offset;
    printf("温度校准: %.1f°C (原始值: %d, 偏移: %.1f)\n", 
           real_temp, sensor->data.raw_data, sensor->offset);
}

static void calibrate_humidity(void* self, HumiditySensor* sensor) {
    float real_humidity = sensor->data.raw_data * 0.1f;
    printf("湿度校准: %.1f%% (原始值: %d)\n", 
           real_humidity, sensor->data.raw_data);
}

// 滤波访问者实现
static void filter_temp(void* self, TempSensor* sensor) {
    // 简单的阈值滤波
    if (sensor->data.raw_data > 1000) {
        printf("温度数据滤波: 数值异常\n");
    } else {
        printf("温度数据滤波: 数值正常\n");
    }
}

static void filter_humidity(void* self, HumiditySensor* sensor) {
    if (sensor->data.raw_data > 1000) {
        printf("湿度数据滤波: 数值异常\n");
    } else {
        printf("湿度数据滤波: 数值正常\n");
    }
}

// 报警访问者实现
static void alarm_temp(void* self, TempSensor* sensor) {
    float real_temp = sensor->data.raw_data * 0.1f + sensor->offset;
    if (real_temp > 50.0f) {
        printf("温度报警: 温度过高 (%.1f°C)\n", real_temp);
    }
}

static void alarm_humidity(void* self, HumiditySensor* sensor) {
    if (sensor->data.raw_data > sensor->threshold) {
        printf("湿度报警: 超过阈值 %d\n", sensor->threshold);
    }
}

// 创建访问者
SensorVisitor* create_calibration_visitor(void) {
    SensorVisitor* visitor = (SensorVisitor*)malloc(sizeof(SensorVisitor));
    visitor->visit_temp = calibrate_temp;
    visitor->visit_humidity = calibrate_humidity;
    return visitor;
}

SensorVisitor* create_filter_visitor(void) {
    SensorVisitor* visitor = (SensorVisitor*)malloc(sizeof(SensorVisitor));
    visitor->visit_temp = filter_temp;
    visitor->visit_humidity = filter_humidity;
    return visitor;
}

SensorVisitor* create_alarm_visitor(void) {
    SensorVisitor* visitor = (SensorVisitor*)malloc(sizeof(SensorVisitor));
    visitor->visit_temp = alarm_temp;
    visitor->visit_humidity = alarm_humidity;
    return visitor;
}

// accept函数实现
void accept_visitor(void* sensor, SensorType type, SensorVisitor* visitor) {
    switch (type) {
        case TEMP_SENSOR:
            visitor->visit_temp(visitor, (TempSensor*)sensor);
            break;
        case HUMIDITY_SENSOR:
            visitor->visit_humidity(visitor, (HumiditySensor*)sensor);
            break;
    }
}

// 销毁函数
void destroy_sensor(void* sensor) {
    free(sensor);
}

void destroy_visitor(SensorVisitor* visitor) {
    free(visitor);
}

4.3 使用示例 (main.c)

#include "sensor_visitor.h"
#include <stdio.h>

int main() {
    // 创建传感器
    TempSensor* temp_sensor = create_temp_sensor(250, -2.5f);  // 25.0°C, -2.5偏移
    HumiditySensor* humidity_sensor = create_humidity_sensor(650, 800);  // 65.0%, 阈值80%
    
    // 创建访问者
    SensorVisitor* calibration = create_calibration_visitor();
    SensorVisitor* filter = create_filter_visitor();
    SensorVisitor* alarm = create_alarm_visitor();
    
    // 处理温度传感器数据
    printf("=== 温度传感器处理 ===\n");
    accept_visitor(temp_sensor, TEMP_SENSOR, calibration);
    accept_visitor(temp_sensor, TEMP_SENSOR, filter);
    accept_visitor(temp_sensor, TEMP_SENSOR, alarm);
    
    // 处理湿度传感器数据
    printf("\n=== 湿度传感器处理 ===\n");
    accept_visitor(humidity_sensor, HUMIDITY_SENSOR, calibration);
    accept_visitor(humidity_sensor, HUMIDITY_SENSOR, filter);
    accept_visitor(humidity_sensor, HUMIDITY_SENSOR, alarm);
    
    // 清理资源
    destroy_sensor(temp_sensor);
    destroy_sensor(humidity_sensor);
    destroy_visitor(calibration);
    destroy_visitor(filter);
    destroy_visitor(alarm);
    
    return 0;
}

5. 代码分析

5.1 关键设计点

  1. 传感器数据结构清晰
  2. 处理逻辑分离
  3. 易于扩展新的处理方法
  4. 资源管理完善

5.2 实现特点

  1. 适合嵌入式系统
  2. 代码简洁高效
  3. 内存占用小
  4. 处理流程清晰

6. 编译和运行

gcc -c sensor_visitor.c -o sensor_visitor.o
gcc -c main.c -o main.o
gcc sensor_visitor.o main.o -o sensor_demo

7. 注意事项

  1. 内存使用要谨慎
  2. 避免过度设计
  3. 考虑实时性要求
  4. 错误处理要完善

8. 改进建议

  1. 添加数据存储功能
  2. 实现数据平滑处理
  3. 添加更多传感器类型
  4. 支持批量数据处理

9. 总结

这个例子展示了访问者模式在嵌入式系统中的实际应用。通过将传感器数据采集和处理逻辑分离,我们可以灵活地添加新的数据处理方法,同时保持代码的清晰和可维护性。

参考资料

  1. 《嵌入式系统设计》
  2. 《C语言程序设计》
  3. 《传感器技术手册》

相关文章:

  • Spring boot 3.4 后 SDK 升级,暨 UI API/MCP 计划
  • 线程控制学习
  • MCP Facade Generator:助力 MCP 协议接口实现的强大工具
  • 【C语言】C语言使用随机数srand,rand
  • nacos-actuator漏洞
  • apt 常见报错及解决方法
  • 本地部署 Firecrawl
  • 【nodejs】爬虫路漫漫,关于nodejs的基操
  • CAJ转PDF:复杂的转换背后有哪些挑战?
  • rocky linux yum源配置
  • 图论 | 98. 所有可达路径
  • 机器学习、深度学习解决方案设计方案通用审核流程(solution architect review)
  • 从扩展黎曼泽塔函数构造物质和时空的结构-5
  • 【页面组件】——1
  • 使用DeepSeek进行审稿和反馈审稿意见相关流程和提示词分享
  • 【算法】常见排序算法(插入排序、选择排序、交换排序和归并排序)
  • LLM之RAG理论(十四)| RAG 最佳实践
  • Pi型隶属函数(Π-shaped Membership Function)的详细介绍及python示例
  • 2025年3月 CCF GESP C++ 二级 真题解析
  • 仅靠prompt,Agent难以自救
  • 全球前瞻|特朗普19日将与俄乌总统分别通话,英国脱欧后首开英欧峰会
  • 淮安市车桥中学党总支书记王习元逝世,终年51岁
  • 国家统计局向多省份反馈统计督察意见
  • “大型翻车现场”科技满满,黄骅打造现代化港口和沿海新城典范
  • 上海“城市文明开放麦”全城总动员,樊振东担任首位上海城市文明大使
  • 证监会:2024年依法从严查办证券期货违法案件739件,作出处罚决定592件、同比增10%