文章目录
1. 什么是观察者模式?
观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
2. 为什么需要观察者模式?
- 实现对象之间的松耦合
- 支持广播通信
- 实现一对多的依赖关系
- 满足开闭原则
- 状态变化的实时通知
3. 实际应用场景
- 传感器数据监控
- 事件处理系统
- 温度监控系统
- 股票价格监控
- 消息订阅系统
4. 代码实现
4.1 UML 关系图
4.2 头文件 (observer.h)
#ifndef OBSERVER_H
#define OBSERVER_H
#include <stdint.h>
#include <stdbool.h>
// 前向声明
typedef struct Subject Subject;
typedef struct Observer Observer;
// 观察者结构体
struct Observer {
void (*update)(Observer* self, float value);
char name[32];
};
// 主题结构体
struct Subject {
Observer* observers[10]; // 最多支持10个观察者
int observer_count;
float temperature; // 温度值
void (*attach)(Subject* self, Observer* observer);
void (*detach)(Subject* self, Observer* observer);
void (*notify)(Subject* self);
void (*set_temperature)(Subject* self, float temp);
};
// 创建函数
Subject* create_subject(void);
Observer* create_temperature_display(const char* name);
Observer* create_temperature_logger(const char* name);
Observer* create_temperature_alarm(const char* name);
// 销毁函数
void destroy_subject(Subject* subject);
void destroy_observer(Observer* observer);
#endif // OBSERVER_H
4.3 实现文件 (observer.c)
#include "observer.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// 主题方法实现
static void attach(Subject* self, Observer* observer) {
if (self->observer_count < 10) {
self->observers[self->observer_count++] = observer;
}
}
static void detach(Subject* self, Observer* observer) {
for (int i = 0; i < self->observer_count; i++) {
if (self->observers[i] == observer) {
// 移除观察者
for (int j = i; j < self->observer_count - 1; j++) {
self->observers[j] = self->observers[j + 1];
}
self->observer_count--;
break;
}
}
}
static void notify(Subject* self) {
for (int i = 0; i < self->observer_count; i++) {
self->observers[i]->update(self->observers[i], self->temperature);
}
}
static void set_temperature(Subject* self, float temp) {
self->temperature = temp;
self->notify(self);
}
// 观察者更新方法实现
static void display_update(Observer* self, float value) {
printf("[显示器 %s] 温度: %.2f°C\n", self->name, value);
}
static void logger_update(Observer* self, float value) {
printf("[记录器 %s] 记录温度: %.2f°C\n", self->name, value);
}
static void alarm_update(Observer* self, float value) {
if (value > 30.0f) {
printf("[警报器 %s] 警告:温度过高 %.2f°C!\n", self->name, value);
}
}
// 创建主题
Subject* create_subject(void) {
Subject* subject = (Subject*)malloc(sizeof(Subject));
subject->observer_count = 0;
subject->temperature = 0.0f;
subject->attach = attach;
subject->detach = detach;
subject->notify = notify;
subject->set_temperature = set_temperature;
return subject;
}
// 创建观察者
Observer* create_temperature_display(const char* name) {
Observer* observer = (Observer*)malloc(sizeof(Observer));
observer->update = display_update;
strncpy(observer->name, name, sizeof(observer->name) - 1);
return observer;
}
Observer* create_temperature_logger(const char* name) {
Observer* observer = (Observer*)malloc(sizeof(Observer));
observer->update = logger_update;
strncpy(observer->name, name, sizeof(observer->name) - 1);
return observer;
}
Observer* create_temperature_alarm(const char* name) {
Observer* observer = (Observer*)malloc(sizeof(Observer));
observer->update = alarm_update;
strncpy(observer->name, name, sizeof(observer->name) - 1);
return observer;
}
// 销毁函数
void destroy_subject(Subject* subject) {
free(subject);
}
void destroy_observer(Observer* observer) {
free(observer);
}
4.4 使用示例 (main.c)
#include "observer.h"
#include <stdio.h>
int main() {
// 创建温度传感器(主题)
Subject* temperature_sensor = create_subject();
// 创建观察者
Observer* display1 = create_temperature_display("Display-1");
Observer* display2 = create_temperature_display("Display-2");
Observer* logger = create_temperature_logger("Logger-1");
Observer* alarm = create_temperature_alarm("Alarm-1");
// 注册观察者
temperature_sensor->attach(temperature_sensor, display1);
temperature_sensor->attach(temperature_sensor, display2);
temperature_sensor->attach(temperature_sensor, logger);
temperature_sensor->attach(temperature_sensor, alarm);
printf("=== 温度变化测试 ===\n");
// 更新温度
temperature_sensor->set_temperature(temperature_sensor, 25.5f);
printf("\n");
temperature_sensor->set_temperature(temperature_sensor, 32.0f);
printf("\n");
// 移除一个显示器
temperature_sensor->detach(temperature_sensor, display2);
printf("移除 Display-2 后的温度显示:\n");
temperature_sensor->set_temperature(temperature_sensor, 28.0f);
// 清理资源
destroy_observer(display1);
destroy_observer(display2);
destroy_observer(logger);
destroy_observer(alarm);
destroy_subject(temperature_sensor);
return 0;
}
5. 代码分析
5.1 关键设计点
- 主题和观察者接口设计
- 观察者注册和移除机制
- 状态更新通知机制
- 观察者列表管理
5.2 实现特点
- 使用函数指针实现多态
- 动态观察者管理
- 类型安全的接口
- 灵活的观察者实现
6. 编译和运行
gcc -c observer.c -o observer.o
gcc -c main.c -o main.o
gcc observer.o main.o -o program
7. 注意事项
- 观察者列表容量限制
- 内存管理安全
- 观察者注册和移除的线程安全
- 避免循环引用
8. 改进建议
- 添加异步通知机制
- 实现优先级机制
- 添加过滤器功能
- 实现观察者分组
9. 总结
观察者模式通过建立对象间的一对多依赖关系,实现了主题状态变化时对所有观察者的自动通知。这种模式在事件处理和状态监控等场景中特别有用。
参考资料
- 《设计模式:可复用面向对象软件的基础》
- 《C语言程序设计》
- 《实时系统设计》