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 关键设计点
- 传感器数据结构清晰
- 处理逻辑分离
- 易于扩展新的处理方法
- 资源管理完善
5.2 实现特点
- 适合嵌入式系统
- 代码简洁高效
- 内存占用小
- 处理流程清晰
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. 注意事项
- 内存使用要谨慎
- 避免过度设计
- 考虑实时性要求
- 错误处理要完善
8. 改进建议
- 添加数据存储功能
- 实现数据平滑处理
- 添加更多传感器类型
- 支持批量数据处理
9. 总结
这个例子展示了访问者模式在嵌入式系统中的实际应用。通过将传感器数据采集和处理逻辑分离,我们可以灵活地添加新的数据处理方法,同时保持代码的清晰和可维护性。
参考资料
- 《嵌入式系统设计》
- 《C语言程序设计》
- 《传感器技术手册》