C 观察者模式 Demo

目录

一、基础描述

二、Demo


最近需要接触到 MySQL 半同步插件,发现其中用到了观察者模式,之前没在 C 中用过,遂好奇心驱使下找了找资料,并写了个 Demo。

一、基础描述

观察者设计模式(Observer Pattern),又称发布-订阅模式(Publish-Subscribe Pattern),是一种行为设计模式。它定义了一种一对多的依赖关系,使得当一个对象(主题或发布者)的状态发生变化时,所有依赖于它的对象(观察者或订阅者)都会得到通知并自动更新。这种模式在软件开发中非常有用,特别是在实现事件处理系统、数据监控系统等方面。

观察者设计模式的主要角色

  • Subject(主题/发布者):
    • 又称被观察者,负责管理观察者列表,并向观察者发送通知。
    • 提供接口让观察者可以注册自己(订阅)和注销自己(取消订阅)。
    • 在状态发生变化时,遍历观察者列表,通知所有注册的观察者。
  • Observer(观察者/订阅者):
    • 订阅主题的更新事件,并执行相应的更新操作。
    • 定义一个接口,以便在得到主题的通知时更新自己。
  • ConcreteSubject(具体主题):
    • 具体的主题实现,包含观察者列表,并在状态发生变化时通知观察者。
  • ConcreteObserver(具体观察者):
    • 具体的观察者实现,处理来自主题的更新事件。

二、Demo

注册两个观察者。发布者状态变量发生修改后,通知观察者,观察者进行响应。

cpp 复制代码
#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(具体观察者):
具体的观察者实现,处理来自主题的更新事件。

相关推荐
理论最高的吻17 小时前
98. 验证二叉搜索树【 力扣(LeetCode) 】
数据结构·c++·算法·leetcode·职场和发展·二叉树·c
时光の尘20 小时前
C语言菜鸟入门·关键字·void的用法
c语言·开发语言·c++·算法·c#·c·关键字
神一样的老师1 天前
C/C++ 优化,strlen 示例
c
Mr. zhihao3 天前
从业务场景学习观察者模式
学习·观察者模式
Mr. zhihao4 天前
观察者模式 vs 不使用观察者模式:商品库存变化的通知
java·观察者模式
万物复苏1014 天前
【汇编】c++游戏开发
开发语言·笔记·游戏·c
石牌桥网管5 天前
用正则表达式检查是IP否为内网地址
java·c++·golang·正则表达式·php·c
Koishi_TvT6 天前
蓝桥杯c++算法学习【3】之思维与贪心(重复字符串、翻硬币、乘积最大、皮亚诺曲线距离【难】:::非常典型的必刷例题!!!)
c++·学习·算法·游戏·贪心算法·蓝桥杯·c
zgy11112229 天前
高阶函数全解析(定义、应用 -- 函数柯理化 反柯理化 发布订阅模式 观察者模式)
观察者模式
杨充9 天前
13.观察者模式设计思想
java·redis·观察者模式