目录
最近需要接触到 MySQL 半同步插件,发现其中用到了观察者模式,之前没在 C 中用过,遂好奇心驱使下找了找资料,并写了个 Demo。
一、基础描述
观察者设计模式(Observer Pattern),又称发布-订阅模式(Publish-Subscribe Pattern),是一种行为设计模式。它定义了一种一对多的依赖关系,使得当一个对象(主题或发布者)的状态发生变化时,所有依赖于它的对象(观察者或订阅者)都会得到通知并自动更新。这种模式在软件开发中非常有用,特别是在实现事件处理系统、数据监控系统等方面。
观察者设计模式的主要角色
- Subject(主题/发布者):
- 又称被观察者,负责管理观察者列表,并向观察者发送通知。
- 提供接口让观察者可以注册自己(订阅)和注销自己(取消订阅)。
- 在状态发生变化时,遍历观察者列表,通知所有注册的观察者。
- Observer(观察者/订阅者):
- 订阅主题的更新事件,并执行相应的更新操作。
- 定义一个接口,以便在得到主题的通知时更新自己。
- ConcreteSubject(具体主题):
- 具体的主题实现,包含观察者列表,并在状态发生变化时通知观察者。
- ConcreteObserver(具体观察者):
- 具体的观察者实现,处理来自主题的更新事件。
二、Demo
注册两个观察者。发布者状态变量发生修改后,通知观察者,观察者进行响应。
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct _observer obs_observer; typedef struct _subject obs_subject; typedef void (*ProcessFun_1)(obs_subject *, obs_observer *); typedef void (*ProcessFun_2)(obs_subject *); // observer struct struct _observer { char name[50]; void (*update)(obs_subject *, obs_observer *); }; // env struct struct _subject { int state; int observer_num; obs_observer **observers; ProcessFun_1 attach; ProcessFun_1 detach; ProcessFun_2 notify; ProcessFun_2 destroy; }; void init_subject(obs_subject *subject, ProcessFun_1 attach, ProcessFun_1 detach, ProcessFun_2 notify, ProcessFun_2 destroy) { subject->state = 0; subject->observer_num = 0; subject->observers = NULL; subject->attach = attach; subject->detach = detach; subject->notify = notify; subject->destroy = destroy; } void init_observer(obs_observer *observer, const char *name) { strcpy(observer->name, name); observer->update = NULL; } void attach(obs_subject *subject, obs_observer *observer) { if ( subject->observer_num == 0 ) { subject->observers = (obs_observer **)malloc(sizeof(obs_subject *)); } else { subject->observers = (obs_observer **)realloc(subject->observers, (subject->observer_num + 1) * sizeof(obs_observer *)); } subject->observers[subject->observer_num++] = observer; } void detach(obs_subject *subject, obs_observer *observer) { int i = 0; for ( i = 0; i < subject->observer_num; i++ ) { if ( subject->observers[i] == observer ) { break; } } if ( i < subject->observer_num ) { subject->observer_num--; subject->observers[i] = subject->observers[subject->observer_num]; subject->observers = (obs_observer **)realloc(subject->observers, subject->observer_num * sizeof(obs_observer *)); } } void concrete_update(obs_subject *subject, obs_observer *observer) { printf("Observer %s received notification: Subject state is now %d\n\n", observer->name, subject->state); } void notify(obs_subject *subject) { for ( int i = 0; i < subject->observer_num; i++ ) { if (subject->observers[i]->update != NULL) { subject->observers[i]->update(subject, subject->observers[i]); } } } void destroy_subject(obs_subject *subject) { if ( subject->observers != NULL ) { free(subject->observers); } } int main(int argc, char **args) { // init observer obs_observer m_observer_1, m_observer_2; init_observer(&m_observer_1, "observer_1"); init_observer(&m_observer_2, "observer_2"); m_observer_1.update = concrete_update; m_observer_2.update = concrete_update; // init env obs_subject m_subject; init_subject(&m_subject, attach, detach, notify, destroy_subject); m_subject.attach(&m_subject, &m_observer_1); m_subject.attach(&m_subject, &m_observer_2); // process m_subject.state = 1; m_subject.notify(&m_subject); m_subject.state = 2; m_subject.notify(&m_subject); // destroy env m_subject.detach(&m_subject, &m_observer_1); m_subject.detach(&m_subject, &m_observer_2); m_subject.destroy(&m_subject); return 0; }
--------------- 分界线------------------
--------------- 分界线------------------
--------------- 分界线------------------
观察者设计模式(Observer Pattern),又称发布-订阅模式(Publish-Subscribe Pattern),是一种行为设计模式。它定义了一种一对多的依赖关系,使得当一个对象(主题或发布者)的状态发生变化时,所有依赖于它的对象(观察者或订阅者)都会得到通知并自动更新。这种模式在软件开发中非常有用,特别是在实现事件处理系统、数据监控系统等方面。
观察者设计模式(Observer Pattern),又称发布-订阅模式(Publish-Subscribe Pattern),是一种行为设计模式。它定义了一种一对多的依赖关系,使得当一个对象(主题或发布者)的状态发生变化时,所有依赖于它的对象(观察者或订阅者)都会得到通知并自动更新。这种模式在软件开发中非常有用,特别是在实现事件处理系统、数据监控系统等方面。
观察者设计模式的主要角色
Subject(主题/发布者):
又称被观察者,负责管理观察者列表,并向观察者发送通知。
提供接口让观察者可以注册自己(订阅)和注销自己(取消订阅)。
在状态发生变化时,遍历观察者列表,通知所有注册的观察者。
Observer(观察者/订阅者):
订阅主题的更新事件,并执行相应的更新操作。
定义一个接口,以便在得到主题的通知时更新自己。
ConcreteSubject(具体主题):
具体的主题实现,包含观察者列表,并在状态发生变化时通知观察者。
ConcreteObserver(具体观察者):
具体的观察者实现,处理来自主题的更新事件。
观察者设计模式(Observer Pattern),又称发布-订阅模式(Publish-Subscribe Pattern),是一种行为设计模式。它定义了一种一对多的依赖关系,使得当一个对象(主题或发布者)的状态发生变化时,所有依赖于它的对象(观察者或订阅者)都会得到通知并自动更新。这种模式在软件开发中非常有用,特别是在实现事件处理系统、数据监控系统等方面。
观察者设计模式的主要角色
Subject(主题/发布者):
又称被观察者,负责管理观察者列表,并向观察者发送通知。
提供接口让观察者可以注册自己(订阅)和注销自己(取消订阅)。
在状态发生变化时,遍历观察者列表,通知所有注册的观察者。
Observer(观察者/订阅者):
订阅主题的更新事件,并执行相应的更新操作。
定义一个接口,以便在得到主题的通知时更新自己。
ConcreteSubject(具体主题):
具体的主题实现,包含观察者列表,并在状态发生变化时通知观察者。
ConcreteObserver(具体观察者):
具体的观察者实现,处理来自主题的更新事件。
观察者设计模式(Observer Pattern),又称发布-订阅模式(Publish-Subscribe Pattern),是一种行为设计模式。它定义了一种一对多的依赖关系,使得当一个对象(主题或发布者)的状态发生变化时,所有依赖于它的对象(观察者或订阅者)都会得到通知并自动更新。这种模式在软件开发中非常有用,特别是在实现事件处理系统、数据监控系统等方面。
观察者设计模式的主要角色
Subject(主题/发布者):
又称被观察者,负责管理观察者列表,并向观察者发送通知。
提供接口让观察者可以注册自己(订阅)和注销自己(取消订阅)。
在状态发生变化时,遍历观察者列表,通知所有注册的观察者。
Observer(观察者/订阅者):
订阅主题的更新事件,并执行相应的更新操作。
定义一个接口,以便在得到主题的通知时更新自己。
ConcreteSubject(具体主题):
具体的主题实现,包含观察者列表,并在状态发生变化时通知观察者。
ConcreteObserver(具体观察者):
具体的观察者实现,处理来自主题的更新事件。