视图
图中包含了两个视图:view_led0 和 view_zigbee。
当 LED0 视图(view_led0)接收到布尔模型发出的更新显示通知时,首先通过模型接口 model_bool_get()获取当前模型的布尔值。若值为 AM_TRUE,则调用 am_led_on()点亮LED0;若值为 AM_FALSE,则调用 am_led_off()熄灭 LED0。
当 zigbee 视图(view_zigbee)接收到布尔模型发出的更新显示通知时,首先通过模型接口 model_bool_get()获取当前模型的布尔值,然后通过 am_zm516x_send ()函数将布尔值通过 zigbee 发送出去。
>>> 9.3.5 软件体系结构
1. 设计模型类图
由于触发事件的模型对象无法预测订阅该事件的所有视图对象,因此要求将视图添加到模型的列表中保存起来。虽然可以将与模型关联的视图对象存放在数组中,却不利于在运行时动态地添加和删除视图,因此选择单向链表。

图 9.15 单向链表
单向链表是由一个 slist_head_t 类型的头结点和若干个 slist_node_t 类型的普通结点“链”起来的,其详见图 9.15,链表的数据结构定义如下:

由于模型需要管理(添加、删除和遍历)存储视图的链表,因此模型需要“持有”整个视图链表的头结点。基于此,需要将链表的 slist_head_t 类型(slist.h)头结点 head 包含在model_t 抽象模型类中作为数据成员:

其中,head 为链表的头结点指针,指向存储视图的链表,其相应的数据结构详见图 9.16。由于视图对象是存储在单向链表中的一个结点,因此需要将链表的 slist_node_t 类型(slist.h)普通结点 node 包含在 observer_t 抽象视图类中作为数据成员:


图 9.16 模型数据
当需要增加视图、删除视图或遍历视图时,将会用到与链表对应的 4 个接口函数。下面将逐一介绍,并在定义了 model_t 类型的模型对象 model 和 observer_t 类型的视图对象observer 的前提下,展示了接口的调用形式。
链表初始化
链表初始化的函数原型如下:

其调用形式如下:

在初始状态时,模型与视图没有任何关系,而添加和删除视图是调用 model_attach()和model_detach()实现的,这是分别调用插入链表结点函数 slist_add_head()和删除链表结点函数 slist_del()实现的。
添加视图
添加视图的 slist_add_head()函数原型如下:

其调用形式如下:

删除视图
删除视图的 slist_del()函数原型如下:

其调用形式如下:


图 9.17 模型内部状态图

如图 9.17 所示在模型内部的链表中添加和删除视图的状态图,图中的 attach/detach 省略了 model_固定前缀。当调用 model_attach()时,则模型关联了一个视图,即从初始状态转移到关联一个视图状态。当再次调用 model_attach()时,则模型对象关联了两个视图,即从关联一个视图状态转移到两个视图状态,以此类推。
在观察对象的声明周期中,如果不需要删除视图的功能,则不要实现 model_detach()。如果不需要在运行时动态地添加和删除视图,即可在初始化时将视图存储在数组中,那么不再需要 model_attach()和 model_detach()函数。
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/ruanjian/article-65228-5.html
不知道是什么品牌味道超级难喝零售假要比RIO便宜2元