C语言-观察者模式
参考代码一
点击查看代码
#include <stdio.h>
#define MAX_OBSERVERS 10
typedef struct Observer{
int Oberver_value;
void (*update)(struct Observer *observer, int value);
}Observer;
typedef struct Subject{
int value;
Observer *observes[MAX_OBSERVERS];
int observeCount;
}Subject;
void updateFunction(Observer *observer, int value)
{
observer->Oberver_value = value;
printf("Observer have updated with value: %d\n", observer->Oberver_value);
}
void registerObserver(Subject *subject, Observer *Observer)
{
if(subject->observeCount < MAX_OBSERVERS)
{
subject->observes[subject->observeCount++] = Observer;
}
}
void notifyObservers(Subject *subject)
{
for(int i = 0; i < subject->observeCount; i++)
{
subject->observes[i]->update(subject->observes[i],subject->value);
//subject->observes[i]->Oberver_value = subject->value;
//printf("Observer[%d] updated with value: %d\n",i+1,subject->observes[i]->Oberver_value);
}
}
void setValue(Subject *subject, int value)
{
subject->value = value;
notifyObservers(subject);
}
int main()
{
Subject subject1; //被观察者
subject1.value = 0;
subject1.observeCount = 0;
Observer observer1; //观察者
observer1.update = updateFunction;
Observer observer2; //观察者
observer2.update = updateFunction;
Observer observer3; //观察者
observer3.update = updateFunction;
registerObserver(&subject1, &observer1); //注册观察者
registerObserver(&subject1, &observer2); //注册观察者
registerObserver(&subject1, &observer3); //注册观察者
setValue(&subject1,100); //设置被观察者的值,并内存通知、更新观察者的值
return 0;
}
参考代码二
点击查看代码
#include <stdio.h>
#include <stdlib.h>
// 定义观察者接口
typedef struct observer {
void (*update)(struct observer *self, int data); // 更新方法
int data; // 存储数据
} observer_t;
// 定义被观察者接口
typedef struct subject {
void (*attach)(struct subject *self, observer_t *observer); // 添加观察者
void (*detach)(struct subject *self, observer_t *observer); // 移除观察者
void (*notify)(struct subject *self); // 通知观察者
int data; // 存储数据
observer_t **observers; // 存储观察者的数组
int size; // 数组的大小
int count; // 数组的元素个数
} subject_t;
// 创建观察者
observer_t *create_observer(void (*update)(observer_t *self, int data), int data) {
observer_t *observer = (observer_t *)malloc(sizeof(observer_t));
observer->update = update;
observer->data = data;
return observer;
}
// 创建被观察者
subject_t *create_subject(int data, int size) {
subject_t *subject = (subject_t *)malloc(sizeof(subject_t));
subject->data = data;
subject->size = size;
subject->count = 0;
subject->observers = (observer_t **)malloc(sizeof(observer_t *) * size);
return subject;
}
// 添加观察者
void attach(subject_t *self, observer_t *observer) {
if (self->count < self->size) {
self->observers[self->count++] = observer;
}
}
// 移除观察者
void detach(subject_t *self, observer_t *observer) {
for (int i = 0; i < self->count; i++) {
if (self->observers[i] == observer) {
for (int j = i; j < self->count - 1; j++) {
self->observers[j] = self->observers[j + 1];
}
self->count--;
break;
}
}
}
// 通知观察者
void notify(subject_t *self) {
for (int i = 0; i < self->count; i++) {
self->observers[i]->update(self->observers[i], self->data);
}
}
// 定义一个具体的观察者A
void updateA(observer_t *self, int data) {
printf("Observer A: data changed from %d to %d\n", self->data, data);
self->data = data;
}
// 定义一个具体的观察者B
void updateB(observer_t *self, int data) {
printf("Observer B: data changed from %d to %d\n", self->data, data);
self->data = data;
}
// 测试代码
int main() {
// 创建被观察者
subject_t *subject = create_subject(0, 10);
subject->attach = attach;
subject->detach = detach;
subject->notify = notify;
// 创建观察者
observer_t *observerA = create_observer(updateA, 0);
observer_t *observerB = create_observer(updateB, 0);
// 添加观察者
subject->attach(subject, observerA);
subject->attach(subject, observerB);
// 改变被观察者的数据
subject->data = 100;
// 通知观察者
subject->notify(subject);
// 移除观察者
subject->detach(subject, observerA);
// 改变被观察者的数据
subject->data = 200;
// 通知观察者
subject->notify(subject);
// 释放内存
free(subject->observers);
free(subject);
free(observerA);
free(observerB);
return 0;
}
参考代码三
点击查看代码
#ifndef _OBSERVER_H_
#define _OBSERVER_H_
typedef struct
{
void (*update_Audio_date)(int *audio_buf);
}interfaces_update_Audio_t;
typedef struct
{
void (*update_video_date)(int *video_buf);
}interfaces_update_Video_t;
#endif
#include "stdio.h"
#include "string.h"
#include <stdint.h>
#include "Observer.h"
#define OBSERVER_MAX_COUNT 10
Observer Audio_Observer;
Observer Video_Observer;
typedef struct observer
{
void (*update)(int *buf);
}Observer;
typedef struct subject
{
Observer *array_observer[OBSERVER_MAX_COUNT];
int (*register_observer)(Observer *observer);
int (*remove_observer)(Observer *observer);
void (*notify_observer)(int *buf);
//void (*other_function)(void);
}Subject;
Subject SwitchBot_Subject;
static int observer_count=0;
void update_video_date(int *buf)
{
//do video function
}
void update_audio_date(int *buf)
{
//do audio fuction
}
int woan_register_observer(Observer *observer)
{
if(observer_count>=OBSERVER_MAX_COUNT)
return 0;
SwitchBot_Subject.array_observer[observer_count++]=observer;
return 1;
}
int woan_remove_observer(Observer *observer)
{
int i=0;
for(i=0;i<observer_count;i++)
{
if(observer==SwitchBot_Subject.array_observer[i])
{
SwitchBot_Subject.array_observer[i]=0;
break;
}
}
return 1;
}
void woan_notify_observer(int *buf)
{
int i=0;
Observer *observer=0;
for(i=0;i<observer_count;i++)
{
observer=SwitchBot_Subject.array_observer[i];
if(observer!=0)
observer->update(buf);
}
}
void init_switchbot_subject()
{
int i=0;
for(i=0;i<OBSERVER_MAX_COUNT;i++)
SwitchBot_Subject.array_observer[i]=0;
SwitchBot_Subject.notify_observer=woan_notify_observer;
SwitchBot_Subject.remove_observer=woan_remove_observer;
SwitchBot_Subject.register_observer=woan_notify_observer;
}
uint8_t get_date(int *buf)
{
//buf get something
}
void check_and_notify()
{
int *buf;
int state=0;
get_date(buf);
if(buf[0] == 0x570f0201)
SwitchBot_Subject.notify_observer(buf);
}
void init_observer(Observer *observer,void (*update)(void))
{
observer->update=update;
}
void add_observer(Subject *subject,Observer *observer)
{
subject->register_observer(observer);
}
void main()
{
interfaces_update_Audio_t *audio_func;
interfaces_update_Video_t *video_func;
init_switchbot_subject();
init_observer(&Audio_Observer,audio_func->update_Audio_date);
init_observer(&Video_Observer,video_func->update_video_date);
init_observer(&Video_Observer,video_func->update_video_date);
add_observer(&SwitchBot_Subject,&Audio_Observer);
add_observer(&SwitchBot_Subject,&Video_Observer);
while(1)
{
check_and_notify();
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通