level 6
西安恩仪联教育
楼主
一、观察者模式简介
1、 观察者模式(Observer Pattern)是一种行为型设计模式,用于定义对象之间的一对多依赖关系:当一个对象(称为被观察者或主题)的状态发生变化时,所有依赖它的对象(称为观察者)都会自动收到通知并更新。
大白话理解观察者模式:
一个被观察者(发布者 / 主题),一群观察者(订阅者);
只要被观察者状态 / 数据发生变化,就会自动通知所有订阅的观察者,大家同步更新、自动响应。
2、理解要点
一对多依赖:一个被观察者可以对应多个观察者。
松耦合:被观察者与观察者之间通过抽象接口交互,彼此不了解具体实现。
自动通知机制:状态变更时,被观察者主动通知所有注册的观察者,无需轮询。
3、主要角色
抽象主题(Subject):提供注册、移除和通知观察者的接口。
具体主题(ConcreteSubject):维护自身状态,状态变化时通知所有观察者。
抽象观察者(Observer):定义更新接口(如 update() 方法)。
具体观察者(ConcreteObserver):实现更新逻辑,响应主题状态变化。
二、举例说明
案例1:公众号订阅
公众号 = 被观察者
关注的粉丝 = 观察者
公众号发文章 → 所有粉丝自动收到推送
案例2:直播间开播提醒
主播开播(状态变化)→ 所有订阅用户弹窗提醒
案例3:闹钟 / 消息推送
系统有新消息 → 所有 APP、弹窗、通知栏统一刷新
三、程序开发场景
1、硬件 / 嵌入式
传感器数据更新 → 所有上层模块(显示、日志、告警)自动刷新
2、UI 开发
底层数据修改 → 界面所有控件自动刷新
3、业务模块解耦
配置变更、系统事件、异常告警全局广播
四、c语言实现观察者模型,可以直接用于工程中。
1、编程步骤:
(1)创建主题
(2)创建观察者
(3)订阅主题
(4)主题状态发生变化时,自动通知所有观察者
2、程序代码如下:
#include <stdio.h>
#include <stdlib.h>
#define MAX_OBSERVERS 10
typedef struct Observer Observer;
typedef void (*ObserverUpdate)(Observer *observer,int data);
struct Observer{
ObserverUpdate update;
void *userDate;
};
typedef struct{
Observer *observers[MAX_OBSERVERS];
int count;
int state;
}Subject;
void subjectInit(Subject *sub)
{
sub->count = 0;
sub->state = 0;
for(int i = 0;i < MAX_OBSERVERS;i++)
{
sub->observers[i] = NULL;
}
}
void subjectAttack(Subject *sub,Observer *obs){
if(sub->count >= MAX_OBSERVERS) return;
sub->observers[sub->count++] = obs;
}
void subjectNotify(Subject *sub)
{
for(int i = 0;i < sub->count;i++)
{
Observer *obs = sub->observers[i];
obs->update(obs,sub->state);
}
}
void subjectSetState(Subject *sub,int newState)
{
printf("状态更新为%d\n",newState);
sub->state = newState;
subjectNotify(sub);
}
void observerAupdate(Observer *observer,int data)
{
printf("收到通知:数据是%d\n",data);
}
void observerBupdate(Observer *observer,int data)
{
printf("收到通知:数据是%d\n",data);
}
int main()
{
//1、创建主题
Subject subject;
subjectInit(&subject);
//2、创建观察者
Observer obsa = {observerAupdate,NULL};
Observer obsb = {observerBupdate,NULL};
//3、订阅主题
subjectAttack(&subject,&obsa);
subjectAttack(&subject,&obsb);
//4、状态改变时通知
subjectSetState(&subject,100);
subjectSetState(&subject,200);
return 0;
}