设计模式专题之C语言-观察者模式

1.简介

观察者模式(Observer Pattern)是一种行为型设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。这种模式在很多场景下都非常有用,比如在GUI应用中,用户界面组件通常需要响应数据模型中的变化。

2.通俗讲解

假设有一个天气预报系统,其中包括一个气象站(Subject)和多个观察者(Observers)。气象站负责收集数据(如温度、湿度等),而观察者则根据这些数据做出相应的反应(如显示在不同的设备上)。

3.实战

首先,我们需要定义一些基本的数据结构:

  1. Subject —— 气象站,用于存储数据和管理观察者列表。
  2. Observer —— 观察者,用于接收数据更新的通知。

3.1.代码

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

// 定义观察者结构体
typedef struct Observer {
    void (*update)(int temp, int humidity); // 更新函数指针
    char *name;                             // 观察者的名称
} Observer;

// 定义主体结构体
typedef struct Subject {
    int temperature;       // 温度
    int humidity;          // 湿度
    Observer **observers;  // 观察者数组
    int numObservers;      // 当前观察者的数量
} Subject;

// 创建新的观察者
Observer *createObserver(char *name, void (*updateFunc)(int, int)) {
    Observer *observer = (Observer *)malloc(sizeof(Observer));
    observer->name = name;
    observer->update = updateFunc;
    return observer;
}

// 创建新的主题
Subject *createSubject() {
    Subject *subject = (Subject *)malloc(sizeof(Subject));
    subject->temperature = 0;
    subject->humidity = 0;
    subject->numObservers = 0;
    subject->observers = NULL;
    return subject;
}

// 添加观察者到主题
void attach(Subject *subject, Observer *observer) {
    subject->observers = (Observer **)realloc(subject->observers, sizeof(Observer *) * (subject->numObservers + 1));
    subject->observers[subject->numObservers++] = observer;
}

// 移除观察者
void detach(Subject *subject, Observer *observer) {
    int i;
    for (i = 0; i < subject->numObservers; i++) {
        if (subject->observers[i] == observer) {
            break;
        }
    }
    if (i < subject->numObservers) {
        subject->numObservers--;
        subject->observers[i] = subject->observers[subject->numObservers];
        subject->observers = (Observer **)realloc(subject->observers, sizeof(Observer *) * subject->numObservers);
    }
}

// 通知所有观察者
void notify(Subject *subject) {
    int i;
    for (i = 0; i < subject->numObservers; i++) {
        Observer *observer = subject->observers[i];
        observer->update(subject->temperature, subject->humidity);
    }
}

// 设置数据
void setData(Subject *subject, int temperature, int humidity) {
    subject->temperature = temperature;
    subject->humidity = humidity;
    notify(subject);
}

// 更新函数示例
void updateTemperature(int temp, int humidity) {
    printf("Temperature Observer: Temperature is now %d, Humidity is %d\n", temp, humidity);
}

void updateHumidity(int temp, int humidity) {
    printf("Humidity Observer: Temperature is now %d, Humidity is %d\n", temp, humidity);
}

int main() {
    Subject *weatherStation = createSubject();
    Observer *temperatureObserver = createObserver("Temperature Observer", updateTemperature);
    Observer *humidityObserver = createObserver("Humidity Observer", updateHumidity);

    attach(weatherStation, temperatureObserver);
    attach(weatherStation, humidityObserver);

    setData(weatherStation, 25, 60);
    setData(weatherStation, 23, 65);

    detach(weatherStation, temperatureObserver);
    setData(weatherStation, 22, 70);

    free(temperatureObserver);
    free(humidityObserver);
    free(weatherStation->observers);
    free(weatherStation);

    return 0;
}

3.2.代码解析

  1. Observer 结构体包含了更新函数指针和观察者的名称。
  2. Subject 结构体包含了温度、湿度以及观察者数组。
  3. attach 和 detach 函数分别用来添加和移除观察者。
  4. notify 函数循环调用每个观察者的更新函数。
  5. setData 函数设置新数据,并通知所有观察者。

3.3.代码运行

  1. 创建一个气象站 weatherStation
  2. 创建两个观察者:temperatureObserver 和 humidityObserver,分别关注温度和湿度的变化。
  3. 将这两个观察者添加到气象站中。
  4. 更新气象站的数据,并通知所有观察者。
  5. 移除其中一个观察者(例如 temperatureObserver),再次更新数据并通知剩余的观察者。
Temperature Observer: Temperature is now 25, Humidity is 60
Humidity Observer: Temperature is now 25, Humidity is 60
Temperature Observer: Temperature is now 23, Humidity is 65
Humidity Observer: Temperature is now 23, Humidity is 65
Humidity Observer: Temperature is now 22, Humidity is 70

3.4.结果分析

  • 当气象站的数据首次更新为温度25度、湿度60%时,两个观察者都收到了通知。
  • 再次更新数据为温度23度、湿度65%时,同样的两个观察者都收到了通知。
  • 当 temperatureObserver 被移除后,仅剩 humidityObserver 接收到了气象站数据的更新通知(温度22度、湿度70%)。

这说明观察者模式在C语言中得到了正确的实现。每当气象站的数据发生变化时,所有注册的观察者都会接收到通知并执行相应的更新操作。如果某个观察者不再需要接收更新,可以将其从气象站中移除,从而避免不必要的通知。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

甜航一直在

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值