观察者模式说明(C语言版本)

观察者模式主要是为了实现一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。下面使用C语言实现了一个具体的应用示例,有需要的可以参考下

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>// 观察者的结构定义
typedef struct {void (*add)(void *data);void (*update)(void *data);void (*delete)(void *data);
} observer_t;// 观察者链表节点定义
typedef struct _observer_list_t {observer_t *observer;struct _observer_list_t *next;
} observer_list_t;// 被观察者定义
typedef struct _subject_t {void *data;observer_list_t *observer; // 观察者链表
} subject_t;// 初始化观察者的更新函数
void init_observer_update(observer_t *observer, void (*update)(void *data)) {observer->update = update;
}// 初始化观察者的添加函数
void init_observer_add(observer_t *observer, void (*add)(void *data)) {observer->add = add;
}// 初始化观察者的删除函数
void init_observer_delete(observer_t *observer, void (*delete)(void *data)) {observer->delete = delete;
}// 加入观察者队列
bool attach_observer(subject_t *subject, observer_t *observer) {observer_list_t *node = (observer_list_t *)malloc(sizeof(observer_list_t));if (!node) return false; // 内存分配失败node->observer = observer;node->next = subject->observer;subject->observer = node;return true;
}// 从观察者队列删除
bool detach_observer(subject_t *subject, observer_t *observer) {observer_list_t *node = subject->observer;observer_list_t *prev = NULL;while (node) {if (node->observer == observer) {if (prev) {prev->next = node->next;} else {subject->observer = node->next;}free(node);return true;}prev = node;node = node->next;}return false; // 未找到观察者
}// 修改被观察数据
void set_observer_data(subject_t *subject, void *value) {subject->data = value;
}// 通知观察者更新
void notify_observer_update(subject_t *subject) {observer_list_t *node = subject->observer;int count = 0;for (; node; node = node->next) {printf("Notify observer update %d. Data: %s\n", count, (char *)subject->data);count++;if (node->observer->update) {node->observer->update(subject->data);}}
}// 通知观察者添加(这个在实际应用中可能不常见,通常只通知更新或删除)
void notify_observer_add(subject_t *subject) {// ...(类似notify_observer_update,但调用add函数)// 这里为了简洁省略,实际应用中根据需要实现
}// 通知观察者删除(同样,这个在标准观察者模式中不常见)
void notify_observer_delete(subject_t *subject) {// ...(类似notify_observer_update,但调用delete函数)// 这里为了简洁省略,实际应用中根据需要实现
}// 初始化主题对象
void init_subject(subject_t *subject) {memset(subject, 0, sizeof(subject_t));
}// 释放主题对象及其所有观察者
void free_subject(subject_t *subject) {observer_list_t *node = subject->observer;while (node) {observer_list_t *temp = node;node = node->next;free(temp);}// 注意:这里没有释放subject->data,因为不清楚其分配方式。在实际应用中需要适当处理。
}

使用示例

// 假设我们有一个简单的字符串观察者,它会打印接收到的字符串
void observer_update(void *data) {printf("Observer received update: %s\n", (char *)data);
}int main() {// 创建一个主题对象subject_t subject;init_subject(&subject);// 创建一个观察者并初始化其更新函数observer_t observer;init_observer_update(&observer, observer_update);// 将观察者附加到主题对象attach_observer(&subject, &observer);// 设置被观察数据并通知观察者set_observer_data(&subject, "Hello, Observer!");notify_observer_update(&subject);// 从主题对象中删除观察者detach_observer(&subject, &observer);// 释放主题对象(在实际应用中,通常在程序结束时进行)free_subject(&subject);return 0;
}

执行结果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/19545.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Zotero PDF Translate插件配置百度翻译api

Zotero PDF Translate插件可以使用几种翻译api&#xff0c;虽然谷歌最好用&#xff0c;但是由于众所周知的原因&#xff0c;不稳定。而cnki有字数限制&#xff0c;有道有时也不行。其他的翻译需要申请密钥。本文以百度为例&#xff0c;进行申请 官方有申请教程&#xff1a; Zot…

无人机遥感:如何助力智慧农业中的农林信息提取?

目录 综合态势分析农作物形态信息提取理论与实践农作物生理生化信息提取理论与实践农作物胁迫信息提取理论与实践农作物产量信息提取理论与实践遥感提取结果的空间表达——GIS制图流程 前言 无人机遥感技术在农林信息提取中的应用已成为智慧农业和生态监测的重要手段。通过搭载…

【线段树 二分查找】P3939 数颜色|普及+

本文涉及知识点 C线段树 C二分查找 P3939 数颜色 题目背景 大样例可在页面底部「附件」中下载。 题目描述 小 C 的兔子不是雪白的&#xff0c;而是五彩缤纷的。每只兔子都有一种颜色&#xff0c;不同的兔子可能有 相同的颜色。小 C 把她标号从 1 到 n n n 的 n n n 只兔…

网络工程师 (44)ARP协议

前言 ARP协议&#xff0c;即地址解析协议&#xff08;Address Resolution Protocol&#xff09;&#xff0c;是一种网络协议&#xff0c;主要用于将网络层的IPv4地址&#xff08;逻辑地址&#xff09;解析为链路层的物理地址&#xff08;通常是MAC地址&#xff09;。 一、基本概…

深入解析 vLLM:高性能 LLM 服务框架的架构之美(一)原理与解析

修改内容时间2.4.1处理请求的流程&#xff0c;引用更好的流程图2025.02.11首发2025.02.08 深入解析 vLLM&#xff1a;高性能 LLM 服务框架的架构之美&#xff08;一&#xff09;原理与解析 深入解析 vLLM&#xff1a;高性能 LLM 服务框架的架构之美&#xff08;二&#xff09;…

Web安全|渗透测试|网络安全

基础入门(P1-P5) p1概念名词 1.1域名 什么是域名&#xff1f; 域名&#xff1a;是由一串用点分隔的名字组成的Internet上某一台计算机或计算机组的名称&#xff0c;用于在数据传输时对计算机的定位标识&#xff08;有时也指地理位置&#xff09;。 什么是二级域名多级域名&am…

JavaSE的基础语法(5)

一.Java中的方法 函数:把完成某一特定功能的代码进行抽取,把他们卸写在一组大括号中,为其命名通过函数名调用即可 Java中的方法:类似于其他语言中的函数(在面向对象的语言中习惯称之为方法,且不能独立存在,需要定义在类中) 将完成某个特定功能的某一段代码封装到一个有名称的代…

springcloud集成gateway

本篇文章只介绍gateway模块的搭建步骤&#xff0c;并无gateway详细介绍 gateway详解请查看&#xff1a;SpringCloudGateway官方文档详解 前置处理 父模块中已指定版本 不知道如何选择版本看这篇&#xff1a; 手把手教你梳理springcloud与springboot与springcloudalibaba的版本…

【Linux】VS code编写cpp文件调用CPLEX求解,Makefile撰写方式

1、先给出Makefile # 目标文件 TARGET my_program# 源文件 SRC blend.cpp# 头文件目录&#xff08;如果有&#xff09; INCLUDES -I./# CPLEX 路径设置&#xff08;根据你的 CPLEX 安装路径&#xff09; CPLEX_INCLUDE -I/mnt/c/users/daniel/Ubuntu/cplex/cplex/include …

DeepSeek24小时写作机器人,持续创作高质量文案

内容创作已成为企业、自媒体和创作者的核心竞争力。面对海量的内容需求&#xff0c;人工创作效率低、成本高、质量参差不齐等问题日益凸显。如何在有限时间内产出高质量内容&#xff1f;DeepSeek写作机器人&#xff0c;一款24小时持续创作的智能工具&#xff0c;为企业和个人提…

开源协议深度解析:理解MIT、GPL、Apache等常见许可证

目录 前言1. MIT协议&#xff1a;自由而宽松的开源许可1.1 MIT协议的主要特点1.2 MIT协议的适用场景 2. GPL协议&#xff1a;自由软件的捍卫者2.1 GPL协议的核心理念2.2 GPL协议的适用场景 3. Apache License 2.0&#xff1a;开源与专利保护的平衡3.1 Apache License 2.0的主要…

第四十四篇--Tesla P40+Janus-Pro-7B部署与测试

环境 系统&#xff1a;CentOS-7 CPU: 14C28T 显卡&#xff1a;Tesla P40 24G 驱动: 515 CUDA: 11.7 cuDNN: 8.9.2.26创建环境 conda create --name trans python3.10torch 2.6.0 transformers 4.48.3克隆项目 git clone https:/…

【前端】自己从头实现一个gpt聊天页面

预览 最小化功能点 主界面&#xff1a;侧边栏会话历史、聊天窗口发送和断开。侧边栏&#xff1a;展示会话列表&#xff0c;每个会话包含多条聊天记录&#xff0c; 通过localstorage本地储存和恢复&#xff0c;会话需要重命名和删除。聊天框&#xff1a;区分一下发送者和回答者…

【第13章:自监督学习与少样本学习—13.1 自监督学习最新进展与实现方法】

凌晨三点的实验室,博士生小王盯着屏幕里正在"自娱自乐"的神经网络——这个没有吃过一张标注图片的模型,正在通过旋转、拼图、填色等游戏任务,悄悄掌握着理解世界的秘诀。这种魔法般的修炼方式,正是当今AI领域最炙手可热的技术:自监督学习。 一、打破数据枷锁:自…

案例-06.部门管理-根据ID查询

一.根据ID查询-接口文档 二.根据ID查询-Controller层 package com.gjw.controller;/*** 部门管理Controller*/import com.gjw.anno.Log; import com.gjw.pojo.Dept; import com.gjw.pojo.Result; import com.gjw.service.DeptService; import com.gjw.service.impl.DeptServi…

【MySQL】使用 JDBC 连接数据库

文章目录 前言1. 认识 JDBC 1.1 概念1.2 好处 2. 使用 JDBC 2.1 安装数据驱动包2.2 把 jar 包导入到项目中2.3 代码编写2.4 测试结果 3. 代码优化4. 源码展示结语 前言 在 MySQL 系列中&#xff0c;我们介绍了很多内容&#xff0c;包括但不限于建库建表&#xff0c;增删查改等…

matlab模拟风场的随机脉动风

1、内容简介 matlab137-模拟风场的随机脉动风 可以交流、咨询、答疑 2、内容说明 略 模拟风场的随机脉动风&#xff0c;并进行相关的统计分析和计算&#xff0c;包括风速谱、空间相关性、自谱、互谱、以及POD&#xff08;Proper Orthogonal Decomposition&#xff09;分解等…

API 接口自动化

HTTP协议 - 白月黑羽 HTTP协议简介 如果客户端是浏览器&#xff0c;如何在chrome浏览器中查看 请求和响应的HTTP消息&#xff1f;按f12-》network 清除当前信息 响应的消息体在Response里看 点preview&#xff0c;可以看响应的消息体展开的格式 HTTP请求消息 请求头 reques…

(四)Axure学习图文教程

Axure中文学习网&#xff1a; Axure中文网 – 交互原型设计软件Axure RP中文正版支持 – 北京口耳相传科技有限公司 一、界面介绍 工具栏&#xff1a;主要操作功能。 站点地图&#xff1a;类似大纲界面&#xff0c;方便理清原型框架及逻辑关系。 元件库&#xff1a;调用所需…

2025年 Java 面试八股文

第一章-Java基础篇 1. Java中的基本数据类型有哪些&#xff1f;⭐ Java中有8种基本数据类型&#xff08;Primitive Types&#xff09;&#xff0c;分别是&#xff1a; byte&#xff1a;8位&#xff0c;-128 ~ 127short&#xff1a;16位&#xff0c;-32,768 ~ 32,767int&…