当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。

  1.观察者模式解决一对多的问题,例如一个模块发生改变时,要通知其他的模块;

  2.被观察者(observable)/主题(subject)中包含所有的观察者(observer);

  3.观察者通过被观察者提供的接口(addObserver)添加自己到被观察者的观察者列表中;

  4.观察者提供一个 update 接口供被观察者调用,已便在发生改变时通知观察者。

  5.避免观察者和被观察者循环应用导致系统崩溃。

observer.h

 1 #ifndef __OBSERVER_H
2 #define __OBSERVER_H
3
4 typedef struct subject Subject;
5 typedef struct observer Observer;
6
7 struct subject {
8 Observer *observer_list;
9 void (*add_observer)(Subject *sub,Observer *obs);
10 void (*delete_observer)(Subject *sub,Observer *obs);
11 int (*count_observers)(Subject *sub);
12 void (*notify_observer)(Subject *sub,Observer *obs,void *arg);
13 void (*notify_all_observers)(Subject *sub,void *arg);
14 };
15
16 struct observer {
17 void (*update)(Observer *obs,Subject *sub,void *arg);
18 Observer *next;
19 };
20
21 void subjectInit(Subject *sub);
22
23 void observerInit(Observer *obs);
24
25 #endif

observer.c

  1 #include <stddef.h>
2 #include "observer.h"
3
4 static void
5 _subjectAddObserver(Subject *sub,Observer *obs)
6 {
7 Observer *_obs = sub->observer_list;
8 obs->next = NULL;
9
10 if(_obs == NULL) {
11 sub->observer_list = obs;
12 return;
13 }
14
15 while(_obs->next != NULL)
16 _obs = _obs->next;
17
18 _obs->next = obs;
19 }
20
21 static void
22 _subjectDeleteObserver(Subject *sub,Observer *obs)
23 {
24 Observer *_obs = sub->observer_list;
25
26 if(_obs == NULL) return;
27
28 if(_obs == obs) {
29 sub->observer_list = _obs->next;
30 return;
31 }
32
33 while(_obs->next != NULL) {
34 if(_obs->next == obs) {
35 _obs->next = obs->next;
36 return;
37 }
38
39 _obs = _obs->next;
40 }
41 }
42
43 static int
44 _subjectCountObservers(Subject *sub)
45 {
46 int cnt = 0;
47 Observer *_obs = sub->observer_list;
48
49 while(_obs != NULL) {
50 cnt ++;
51 _obs = _obs->next;
52 }
53
54 return cnt;
55 }
56
57 static void
58 _subjectNotifyObserver(Subject *sub,Observer *obs,void *arg)
59 {
60 obs->update(obs,sub,arg);
61 }
62
63 static void
64 _subjectNotifyAllObservers(Subject *sub,void *arg)
65 {
66 Observer *_obs = sub->observer_list;
67
68 while(_obs != NULL) {
69 _obs->update(_obs,sub,arg);
70 _obs = _obs->next;
71 }
72 }
73
74 void
75 subjectInit(Subject *sub)
76 {
77 sub->observer_list = NULL;
78 sub->add_observer = _subjectAddObserver;
79 sub->delete_observer = _subjectDeleteObserver;
80 sub->count_observers = _subjectCountObservers;
81 sub->notify_observer = _subjectNotifyObserver;
82 sub->notify_all_observers = _subjectNotifyAllObservers;
83 }
84
85 static void
86 _observerUpdate(Observer *obs,Subject *sub,void *arg)
87 {
88 (void)obs;
89 (void)sub;
90 (void)arg;
91
92 /** You should override the update function **/
93 while(1) {
94 ;
95 }
96 }
97
98 void
99 observerInit(Observer *obs)
100 {
101 obs->update = _observerUpdate;
102 obs->next = NULL;
103 }

实体观察者类

1 struct observerExtend {
2 Observer obs;
3 Subject *sub;
4 int id;
5 };
6
7 typedef struct observerExtend ObserverExtend;
8
9 void obExtdinit(ObserverExtend *extd);
 1 #include <stdio.h>
2 #include "observer_extend.h"
3
4 static void
5 update(Observer *obs,Subject *sub,void *arg)
6 {
7 ObserverExtend *extd = (ObserverExtend *)obs;
8 printf("observer %d, arg %d\r\n",extd->id, arg);
9 }
10
11 void
12 obExtdinit(ObserverExtend *extd)
13 {
14 observerInit(&extd->obs);
15 extd->obs.update = update;
16 extd->sub->add_observer(extd->sub, &extd->obs);
17 }

嵌入式C设计模式 - 观察者模式的更多相关文章

  1. 18. 星际争霸之php设计模式--观察者模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

  2. linkin大话设计模式--观察者模式

    linkin大话设计模式--观察者模式 观察者模式定义了对象间的一对多依赖关系,让一个或者多个观察者观察一个对象主题.当主题对象的状态发生改变的时候,系统能通知所有的依赖于此对象的观察者对象,从而能自 ...

  3. java设计模式--观察者模式(Observer)

    java设计模式--观察者模式(Observer) java设计模式--观察者模式(Observer) 观察者模式的定义: 定义对象间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖于它的 ...

  4. js设计模式-观察者模式

    定义: 观察者模式又叫发布订阅模式,它定义了对象间的一种一对多的依赖关系.观察者模式让两个对象松耦合地联系在一起,虽然不太清楚彼此的细节,但这不影响他们之间的互相通信. 思路 定义一个对象,在对象中实 ...

  5. 【设计模式】Java设计模式 - 观察者模式

    [设计模式]Java设计模式 - 观察者模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 @一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长 ...

  6. 【学习笔记】C/C++ 设计模式 - 观察者模式

    前言 估计 2020 年写应用程序的机会比较多,之前一直在做嵌入式驱动程序和Android系统定制方面的工作,在应用程序方面积累的不是很多,因此迫切需要多学学应用编程这方面的知识. 之前在写小的应用程 ...

  7. [Head First设计模式]山西面馆中的设计模式——观察者模式

    系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 引言 不知不自觉又将设计模式融入生活了,吃个饭也不得安生,也发现生活中的很多场景,都可以用设计模式来模拟.原来设计模式就在 ...

  8. javascript 设计模式-----观察者模式

    观察者模式在设计模式中被重点提到,因为它应用的场景非常多,而且在模块化设计当中扮演着非常重要的角色.MVC模式中最底层的就是观察者模式,当下流行的javascript框架backbone就是很好地运用 ...

  9. c#设计模式-观察者模式

    Observer 与 Subject 互为耦合,但是这种耦合的双方都依赖于抽象,而不依赖于具体. 一.观察者模式 目的 我们都知道解决一个问题有N种解决方式,但在面向对象的设计中如何能做到“高内聚,低 ...

  10. JAVA 设计模式 观察者模式

    用途 观察者模式 (Observer) 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象. 这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己. 观 ...

随机推荐

  1. net core api上传下载大文件 413、400错误 IIS服务器

    1.背景 上传文件时,如果文件太大(一般指超过30M的文件)会报错,报错原因如下 IIS服务器:限制大文件上传,报413错误码 net  core api项目:限制大文件上传,报400错误码 2.首先 ...

  2. angular 封装http请求、解决跨域问题

    第一部分:封装http请求 1.定义 ResultDataModel export interface ResultDataModel<T> { success: boolean; err ...

  3. LeetCode-1219 黄金矿工

    来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/path-with-maximum-gold 题目描述 你要开发一座金矿,地质勘测学家已经探明了这 ...

  4. DesignPatternPrinciple-设计模式原则

    1. 单一职责原则(Single Responsibility Principle)类T负责两个不同的职责:职责P1,职责P2. using System; using System.Collecti ...

  5. Python算法教程_中文版书籍 程序员必备 免费下载

    Python算法教程_中文版免费下载地址 提取码:55kh 内容简介  · · · · · · 本书用Python语言来讲解算法的分析和设计.本书主要关注经典的算法,但同时会为读者理解基本算法问题和解 ...

  6. leetcode 31. 下一个排列 【时间击败 100%】 【内存击败 92.17%】

    对于该题,我本来兴致勃勃地想到了两个优化,但从提交结果来看根本看不出来有什么区别,但我发4我说的都是真的 -3- 1 public void nextPermutation(int[] nums) { ...

  7. 深入理解 JVM -- 垃圾收集器与内存分配策略

    程序计数器.虚拟机栈.本地方法栈 3个区域随线程而生,随线程而灭:栈中的栈帧随着方法的进入和退出而有条不紊地执行着出栈和入栈操作.每一个栈帧中分配多少内存基本上是在类结构确定下来时就已知的(尽管在运行 ...

  8. 多个pie环形图 逆时针旋转

    效果图如下  代码如下 data = [ { name: "经济目的", value: 754, }, { name: "网络安全爱好者", value: 61 ...

  9. sql server 最近执行语句统计查询分析

    查询语句: select * from ( SELECT [RowNumber],DATEDIFF(second, StartTime, isnull(EndTime ,StartTime)) 执行时 ...

  10. 在k8s中使用harbor仓库

    在k8s中使用harbor仓库 修改每个node上的docker认证仓库 将每个node节点上的docker同样需要配置可信任仓库 vi /etc/docker/daemon.json #修改为 {& ...