观察者模式是一种常见的设计模式,它允许对象在状态改变时自动通知它们的观察者。下面是一个使用 C 语言实现观察者模式的示例:
#include <stdio.h>
#include <stdlib.h>
// 观察者接口
typedef struct Observer {
void (*update)(struct Observer*, int);
} Observer;
// 被观察者接口
typedef struct Subject {
Observer** observers;
int num_observers;
void (*attach)(struct Subject*, Observer*);
void (*detach)(struct Subject*, Observer*);
void (*notify)(struct Subject*, int);
} Subject;
// 创建一个观察者
Observer* create_observer() {
Observer* observer = malloc(sizeof(Observer));
observer->update = NULL;
return observer;
}
// 创建一个被观察者
Subject* create_subject() {
Subject* subject = malloc(sizeof(Subject));
subject->observers = NULL;
subject->num_observers = 0;
subject->attach = NULL;
subject->detach = NULL;
subject->notify = NULL;
return subject;
}
// 将观察者添加到被观察者的观察者列表中
void attach(Subject* subject, Observer* observer) {
subject->observers = realloc(subject->observers, (subject->num_observers + 1) * sizeof(Observer*));
subject->observers[subject->num_observers++] = observer;
}
// 将观察者从被观察者的观察者列表中移除
void detach(Subject* subject, Observer* observer) {
for (int i = 0; i < subject->num_observers; i++) {
if (subject->observers[i] == observer) {
for (int j = i; j < subject->num_observers - 1; j++) {
subject->observers[j] = subject->observers[j + 1];
}
subject->num_observers--;
subject->observers = realloc(subject->observers, subject->num_observers * sizeof(Observer*));
break;
}
}
}
// 通知被观察者的所有观察者状态发生了改变
void notify(Subject* subject, int data) {
for (int i = 0; i < subject->num_observers; i++) {
subject->observers[i]->update(subject->observers[i], data);
}
}
// 实现观察者接口的具体观察者
typedef struct ConcreteObserver {
Observer base;
int data;
} ConcreteObserver;
// 实现观察者接口的具体观察者的更新方法
void update(Observer* observer, int data) {
ConcreteObserver* concrete_observer = (ConcreteObserver*)observer;
concrete_observer->data = data;
printf("Observer %p received data: %d\n", observer, data);
}
int main() {
Subject* subject = create_subject();
subject->attach = attach;
subject->detach = detach;
subject->notify = notify;
Observer* observer1 = create_observer();
observer1->update = update;
ConcreteObserver concrete_observer1 = { *observer1, 0 };
subject->attach(subject, (Observer*)&concrete_observer1);
Observer* observer2 = create_observer();
observer2->update = update;
ConcreteObserver concrete_observer2 = { *observer2, 0 };
subject->attach(subject, (Observer*)&concrete_observer2);
subject->notify(subject, 123);
subject->detach(subject, observer2);
subject->notify(subject, 456);
free(observer1);
free(observer2);
free(subject->observers);
free(subject);
return 0;
}
在上面的代码中,我们定义了一个 Observer 接口和一个 Subject 接口,然后实现了它们的具体实现。Observer 接口只有一个 update 方法,用于接收被观察者状态改变的通知。Subject 接口包括一个观察者列表和三个方法:attach 用于将观察者添加到列表中,detach 用于将观察者从列表中移除,notify 用于通知所有观察者状态发生了改变。我们还实现了一个具体的观察者 ConcreteObserver,它包含一个 Observer 成员和一个数据成员,用于存储被观察者状态的值。在 main 函数中,我们创建了一个被观察者和两个观察者,然后将这两个观察者添加到被观察者的观察者列表中。接着,我们调用了被观察者的 notify 方法,通知所有观察者状态发生了改变,并输出了观察者接收到的数据。最后,我们将一个观察者从列表中移除,再次调用 notify 方法,观察到只有一个观察者接收到了数据。