C语言-观察者模式详解与实践

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 关键设计点

  1. 主题和观察者接口设计
  2. 观察者注册和移除机制
  3. 状态更新通知机制
  4. 观察者列表管理

5.2 实现特点

  1. 使用函数指针实现多态
  2. 动态观察者管理
  3. 类型安全的接口
  4. 灵活的观察者实现

6. 编译和运行

gcc -c observer.c -o observer.o
gcc -c main.c -o main.o
gcc observer.o main.o -o program

7. 注意事项

  1. 观察者列表容量限制
  2. 内存管理安全
  3. 观察者注册和移除的线程安全
  4. 避免循环引用

8. 改进建议

  1. 添加异步通知机制
  2. 实现优先级机制
  3. 添加过滤器功能
  4. 实现观察者分组

9. 总结

观察者模式通过建立对象间的一对多依赖关系,实现了主题状态变化时对所有观察者的自动通知。这种模式在事件处理和状态监控等场景中特别有用。

参考资料

  1. 《设计模式:可复用面向对象软件的基础》
  2. 《C语言程序设计》
  3. 《实时系统设计》
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值