在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

基于觀察者模式設計的框架-REB,使代碼模塊化

Rice嵌入式開發技術分享 ? 來源:Rice 嵌入式開發技術分享 ? 作者:Rice 嵌入式開發技 ? 2023-10-17 09:35 ? 次閱讀

設計模式里面的觀察者模式,一直是作者想去設計一套框架來闡述這一個模式,因此REB(Rice Event Broker)就是為了完成觀察者模式的一個框架。

觀察者模式

聊REB之前,我們聊聊觀察者模式帶給我們特性,他能對我們框架設計提供什么好處。

什么是觀察者模式

觀察者模式(Observer Pattern)是一種行為設計模式,用于定義對象之間的一對多依賴關系,使得一個對象的狀態變化會通知其所有依賴者并自動更新它們的狀態。這個模式涉及兩種主要類型的對象:

被觀察者:也稱為主題或可觀察者,是一個對象,它維護一組觀察者(或依賴者)并提供方法來添加、刪除和通知這些觀察者。當被觀察者的狀態發生變化時,它會通知所有已注冊的觀察者。

觀察者:觀察者是依賴于被觀察者的對象,它們實現一個接口或抽象類,包含一個更新方法(通常稱為update),用于接收并處理被觀察者的狀態變化通知。

觀察者模式工作流程

被觀察者注冊觀察者:被觀察者維護一個觀察者列表,并提供注冊(添加)和注銷(刪除)觀察者的方法。

被觀察者狀態變化:當被觀察者的狀態發生變化,它會遍歷其觀察者列表,調用每個觀察者的更新方法,將狀態變化通知給它們。

觀察者響應:每個觀察者在接收到通知后會執行自己的更新邏輯,以響應被觀察者的狀態變化。

觀察者模式優勢

「解耦性:」觀察者模式可以幫助降低對象之間的耦合度。被觀察者和觀察者之間的關系是松散的,它們可以獨立演化,而不會影響彼此的具體實現。

「可擴展性:」你可以輕松地添加新的觀察者,而不需要修改被觀察者的代碼。這種擴展性使你能夠動態地增加或刪除觀察者,以滿足不同的需求。

「通知機制:」觀察者模式允許被觀察者通知觀察者,從而使觀察者能夠在適當的時候進行響應。這可以幫助確保數據的一致性,因為觀察者會立即知道被觀察者的狀態變化。

「分布式事件處理:」觀察者模式常用于實現分布式事件處理系統,其中多個觀察者可以遠程訂閱和接收事件通知。

「可重用性:」觀察者模式可以在不同的應用中重復使用,因為它是一個通用的設計模式,不受特定應用領域的限制。

「靈活性:」觀察者模式可以用于許多不同的場景,如用戶界面更新、事件處理、數據同步等,使得代碼更加靈活和可維護。

「支持一對多關系:」觀察者模式支持一對多的依賴關系,這意味著一個被觀察者可以同時通知多個觀察者,從而實現多個對象之間的協同工作。

觀察者模式例子

物聯網協議MQTT:MQTT(Message Queuing Telemetry Transport,消息隊列遙測傳輸協議),是一種基于發布/訂閱(publish/subscribe)模式的“輕量級”通訊協議。

Android的EventBus:EventBus是一個基于發布者/訂閱者模式的事件總線框架。

REB框架設計

REB框架圖

9c0afb10-6c0f-11ee-b3e3-92fbcf53809c.png

REB框架說明

REB框架分為3層:osal(OS抽象層),REB核心層(包含發布者,觀察者,中間人),應用層(調用REB的模塊或應用)。

osal(OS抽象層):為了能讓此框架應用于不同的操作系統,且不用修改框架本身,所以提供os適配層。

REB核心層(包含發布者,觀察者,中間人):框架的三大角色,它們三者互相依賴。

publisher(發布者):REB框架的發布者支持4種接口:默認發送接口,默認發送完釋放數據內存釋放接口,緊急發送接口,緊急發送完數據內存釋放接口。

observer(觀察者):REB框架的觀察者支持3種接口:信號接收接口,回調接收接口,線程接收接口。

broker(中間人):REB框架的中間人支持兩種接口:觀察者只觀察一次接口,觀察者觀察多次接口。

應用層(調用REB的模塊或應用):上層應用或者模塊,相互獨立,互不依賴。

REB是以事件為導向,事件類型由主事件類型和次事件類型組成,事件類型占用32個位,主事件類型占高16位,次事件類型占低16位。一般:以網絡為例:主事件類型為:net_type,次事件類型為:link_up,link_down等。

REB目錄結構

├─adapter
│├─cmsis
│|├─reb_mutex.c//cmsismutex適配層
│|├─reb_queue.c//cmsisqueue適配層
│|├─reb_sem.c//cmsissem適配層
│|└─reb_task.c//cmsistask適配層
│└─rtthread
│├─reb_mutex.c//rtthreadmutex適配層
│├─reb_queue.c//rtthreadqueue適配層
│├─reb_sem.c//rtthreadsem適配層
│└─reb_task.c//rtthreadtask適配層
├─example
│└─reb_rtt_example.c//rtthread平臺實例
├─include
│├─reb_broker.h//reb中間人的頭文件
│├─reb_cfg.h//reb參數配置文件
│├─reb_def.h//reb框架通用接口定義
│├─reb_observer.h//reb觀察者的頭文件
│└─reb_publisher.h//reb發布者的頭文件
└─src
├─reb_broker.c//reb中間人的源文件
├─reb_publisher.c//reb觀察者的源文件
└─reb_observer.c//reb發布者的源文件

REB接口說明

broker接口

接口 說明
broker_create 創建broker
broker_delete 刪除broker
broker_observer_attach_once 關聯觀察者到broker中,并只觀察一次
broker_observer_attach 關聯觀察者到broker中,并只觀察多次
broker_observer_detach 從broker中脫離觀察者

創建broker

在使用該框架時,必須要通過此接口創建broker,它是發布者和觀察者的中間人。

reb_statusbroker_create(void);

「參數」 「描述」
-- --
「返回」 ——
REB_OK broker創建成功
REB_ERROR broker創建失敗

刪除broker

當不再使用該框架時,可以調用此接口刪除broker。

reb_statusbroker_delete(void);

「參數」 「描述」
-- --
「返回」 ——
REB_OK broker刪除成功
REB_ERROR broker刪除失敗

關聯觀察者到broker中,并只觀察一次

我創建的觀察者之后,需要通過此接口將觀察者關聯到broker中。當發布者發布事件,可以通過broker找到對用的觀察者。使用該接口觀察者只觀察一次事件。

reb_statusbroker_observer_attach_once(observer_base*obs);

「參數」 「描述」
obs 觀察者對象
「返回」 ——
REB_OK 關聯觀察者到broker中,成功
REB_ERROR 關聯觀察者到broker中,失敗

關聯觀察者到broker中,并只觀察多次

我創建的觀察者之后,需要通過此接口將觀察者關聯到broker中。當發布者發布事件,可以通過broker找到對用的觀察者。使用該接口觀察者只觀察多次事件。

reb_statusbroker_observer_attach(observer_base*obs);

「參數」 「描述」
obs 觀察者對象
「返回」 ——
REB_OK 關聯觀察者到broker中,成功
REB_ERROR 關聯觀察者到broker中,失敗

從broker中脫離觀察者

reb_statusbroker_observer_detach(observer_base*obs);

「參數」 「描述」
obs 觀察者對象
「返回」 ——
REB_OK 觀察者從broker中脫離,成功
REB_ERROR 觀察者從broker中脫離,失敗

observer接口

接口 說明
observer_signal_create 創建信號模式的觀察者,只接收事件信號,不傳輸數據的觀察者
observer_signal_wait 信號模式的觀察者,等待同步信號
observer_callback_create 創建回調模式的觀察者
observer_task_create 創建任務模式的觀察者
observer_delete 刪除觀察者

創建信號模式的觀察者

該接口是創建信號模式的觀察者,它只接收事件信號,不傳輸數據的。

observer_base*observer_signal_create(uint16_ttype,uint16_tsub_type);

「參數」 「描述」
type 觀察者觀察的主事件類型
sub_type 觀察者觀察的次事件類型
「返回」 ——
obs 觀察者創建成功
NULL 觀察者創建失敗

信號模式的觀察者,等待同步信號

該接口是信號模式的觀察者,用戶層需要通過一個任務監聽觀察事件的同步信號接口。

reb_statusobserver_signal_wait(observer_base*base,reb_time_ttimeout);

「參數」 「描述」
base 觀察者對象
timeout 觀察事件的超時事件
「返回」 ——
REB_OK 觀察到對應事件
OTHER 觀察失敗

創建回調模式的觀察者

該接口是創建回調模式的觀察者,當事件產生時,broker會通過回調的方式通知觀察者事件的到來。

observer_base*observer_callback_create(uint16_ttype,
uint16_tsub_type,
obs_callback_cbcb,
void*arg);

「參數」 「描述」
type 觀察者觀察的主事件類型
sub_type 觀察者觀察的次事件類型
cb 事件產生時,回調的接口函數
arg 回調函數的用戶數據
「返回」 ——
obs 觀察者創建成功
NULL 觀察者創建失敗

創建任務模式的觀察者

該接口是創建任務模式的觀察者,當事件產生時,broker會通過創建一個線程,然后由獨立的線程將事件通知給觀察者。

observer_base*observer_task_create(uint16_ttype,
uint16_tsub_type,
obs_task_cbrun,
void*arg,
uint32_tstack_size,
uint32_tprio);

「參數」 「描述」
type 觀察者觀察的主事件類型
sub_type 觀察者觀察的次事件類型
run 事件產生時,線程的處理函數
arg 線程處理函數的用戶數據
stack_size 線程的??臻g大小
prio 線程的優先級
「返回」 ——
obs 觀察者創建成功
NULL 觀察者創建失敗

從broker中脫離觀察者

reb_statusobserver_delete(observer_base*base);

「參數」 「描述」
base 觀察者對象
「返回」 ——
REB_OK 觀察者刪除成功
REB_ERROR 觀察者刪除失敗

publisher接口

接口 說明
publisher_factory_create 創建發布者工廠
publisher_send 發布者默認發送消息
publisher_send_with_free 發布者默認發送消息,發送完成之后把消息緩沖刪除
publisher_urgent_send 發布者發送緊急消息
publisher_urgent_send_with_free 發布者發送緊急消息,發送完成之后把消息緩沖刪除

創建發布者工廠

該接口是創建發布者工廠,提供事件隊列,使發布消息處于非阻塞式發送

reb_statuspublisher_factory_create(pub_notifynotify);

「參數」 「描述」
notify 事件通知回調,當發布者發布消息之后,通過回調通知broker
「返回」 ——
REB_OK 發布者工廠創建成功
REB_ERROR 發布者工廠創建失敗

發布者默認發送消息

該接口是發布者發布事件接口,它是采用先進先出的方式發送消息

reb_statuspublisher_send(uint16_ttype,uint16_tsub_type,
uint32_tdata,reb_time_ttimeout);

「參數」 「描述」
type 發布消息的主事件類型
sub_type 發布消息的次事件類型
data 發布消息的數據
timeout 發布消息的超時時間
「返回」 ——
REB_OK 發布消息成功
OTHER 發布消息失敗

發布者默認發送消息,發送完成之后把消息緩沖刪除

該接口是發布者發布事件接口,它是采用先進先出的方式發送消息,并且將消息發送給所有觀察者之后,數據的內存會執行釋放。

reb_statuspublisher_send_with_free(uint16_ttype,uint16_tsub_type,
uint32_tdata,reb_time_ttimeout);

「參數」 「描述」
type 發布消息的主事件類型
sub_type 發布消息的次事件類型
data 發布消息的數據
timeout 發布消息的超時時間
「返回」 ——
REB_OK 發布消息成功
OTHER 發布消息失敗

發布者發送緊急消息

該接口是發布者發布事件接口,它是采用插隊的方式發送消息,它會將發布的消息插入消息隊列的頭部。

reb_statuspublisher_urgent_send(uint16_ttype,uint16_tsub_type,
uint32_tdata,reb_time_ttimeout);

「參數」 「描述」
type 發布消息的主事件類型
sub_type 發布消息的次事件類型
data 發布消息的數據
timeout 發布消息的超時時間
「返回」 ——
REB_OK 發布消息成功
OTHER 發布消息失敗

發布者發送緊急消息,發送完成之后把消息緩沖刪除

該接口是發布者發布事件接口,它它是采用插隊的方式發送消息,它會將發布的消息插入消息隊列的頭部。并且將消息發送給所有觀察者之后,數據的內存會執行釋放。

reb_statuspublisher_urgent_send_with_free(uint16_ttype,uint16_tsub_type,
uint32_tdata,reb_time_ttimeout);

「參數」 「描述」
type 發布消息的主事件類型
sub_type 發布消息的次事件類型
data 發布消息的數據
timeout 發布消息的超時時間
「返回」 ——
REB_OK 發布消息成功
OTHER 發布消息失敗

REB驗證

創建三個不同模式的觀察者,并關聯到broker中。

通過多次不發布事件,查看觀察者是否能接收到事件。

#include"rtthread.h"
#include"reb_broker.h"
#include"reb_observer.h"
#include"reb_publisher.h"

observer_base*obs_signal;
observer_base*obs_call;
observer_base*obs_task;

voidsig_thread_handle(void*arg)//信號模式觀察者監聽同步信號
{
while(1){
if(observer_signal_wait(obs_signal,RT_WAITING_FOREVER)==REB_OK){
rt_kprintf("signal:recvsuccessrn");
}
}
}

voidobs_callback(uint32_tevent,uint32_tdata,void*arg)//回調模式觀察者處理函數
{
rt_kprintf("call:event:0x%08x,data:%srn",event,(char*)data);
}

voidobs_task_fun(uint32_tevent,uint32_tdata,void*arg)//任務模式觀察者任務處理函數
{
rt_kprintf("task:event:0x%08x,data:%srn",event,(char*)data);
}

intreb_init(void)
{
rt_thread_tsignal_thread=NULL;

broker_create();//broker創建

obs_signal=observer_signal_create(1,REB_ALL_MINOR_TYPE);//創建信號模式觀察者

signal_thread=rt_thread_create("sig_thread",sig_thread_handle,NULL,1024,10,20);//創建線程,等待信號模式下的事件
rt_thread_startup(signal_thread);

obs_call=observer_callback_create(1,REB_ALL_MINOR_TYPE,obs_callback,NULL);//創建回調模式觀察者

obs_task=observer_task_create(1,REB_ALL_MINOR_TYPE,obs_task_fun,NULL,1024,15);//創建任務模式觀察者

broker_observer_attach(obs_signal);//關聯信號模式觀察者
broker_observer_attach(obs_call);//關聯回調模式觀察者
broker_observer_attach_once(obs_task);//關聯任務模式觀察者

returnRT_EOK;
}
INIT_COMPONENT_EXPORT(reb_init);

intreb_test(void)
{
char*data="RiceChen";
publisher_send(1,1,(int)data,1000);//發布事件
publisher_send(1,2,(int)data,1000);//發布事件
publisher_send(1,3,(int)data,1000);//發布事件
}
MSH_CMD_EXPORT(reb_test,RiceEventbrokertest);
9c1e5e4e-6c0f-11ee-b3e3-92fbcf53809c.jpg

REB總結

REB優點:

REB提供了多種的模式的觀察者,可以根據需求選擇不同模式的觀察者。

REB的發布者可以支持緊急事件發布和非緊急事件發送,保證了事件的及時響應。

REB增加了OSAL層,使其不依賴于任何的平臺,可以很方便的移植到其他平臺。

REB缺點:

REB的事件處理采用串行的方式,當事件積累多了,負載會比較大(后續優化)。

REB已經被合并到RT-THREAD軟件包中,并且得到RT-THREAD技術總監的認可。開源鏈接:https://github.com/RiceChen0/reb

9c3414c8-6c0f-11ee-b3e3-92fbcf53809c.png ?

審核編輯 黃宇

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 框架
    +關注

    關注

    0

    文章

    403

    瀏覽量

    17543
  • 模塊化
    +關注

    關注

    0

    文章

    334

    瀏覽量

    21449
  • 代碼
    +關注

    關注

    30

    文章

    4828

    瀏覽量

    69057
收藏 人收藏

    評論

    相關推薦

    為什么要開發模塊化測試框架?

    為什么要開發模塊化測試框架?具體該怎么做?
    發表于 08-08 06:06

    CC2540廣播角色和觀察者角色切換代碼怎么編寫?

    希望一個CC2540先通過觀察者角色獲取其他廣播的廣播數據,然后在切換為廣播角色將這些數據廣播給另外一個觀察者?這樣就需要編程實現觀察者
    發表于 03-16 10:27

    RN4020觀察者模式無法正常工作怎么回事

    中心,支持MLDP,并使UART流控制R,1//重新引導,使更改生效J,1//觀察者模式你對這個問題有什么想法?謝謝,弗朗西斯科
    發表于 04-22 09:03

    屬性觀察者的特點

    屬性觀察者,類似于觸發器。用來監視屬性的除初始之外的屬性值變化,當屬性值發生改變時可以對此作出響應。有如下特點: 1,不僅可以在屬性值改變后觸發didSet,也可以在屬性值改變前觸發willSet
    發表于 11-04 07:10

    觀察者模式在嵌入式編程設計中有何作用

    觀察者模式是最常見的模式之一。這種模式提供一種方法來時對象“監聽”其他對象,而不需要修改任何數據服務器。在嵌入式領域,這意味著數據能夠很容易分享給其他元素。
    發表于 12-22 08:31

    基于觀察者模式的屏幕布局控件設計

    觀察者模式作為設計模式中行為模式的一種,解決了上述具有一對多依賴關系對象重用問題。文中在分析觀察者模式
    發表于 02-13 16:20 ?4次下載
    基于<b class='flag-5'>觀察者</b><b class='flag-5'>模式</b>的屏幕布局控件設計

    全面提升自動測試,NI TestStand 2012新模塊化框架

    NI TestStand 2012采用全新的模塊化框架,能夠簡化自動測試的開發和報告生成。
    發表于 11-06 17:42 ?1791次閱讀

    Java設計模式分析之觀察者

    觀察者模式的流程跟報紙訂閱方式一致,即:觀察者模式=出版+訂閱,只是名稱不一樣,出版
    發表于 09-26 17:36 ?0次下載

    在 Java8 環境下實現觀察者模式的實例分析

    觀察者(Observer)模式又名發布-訂閱(Publish/Subscribe)模式,是四人組(GoF,即 Erich Gamma、Richard Helm、Ralph Johnson
    發表于 10-12 16:09 ?0次下載
    在 Java8 環境下實現<b class='flag-5'>觀察者</b><b class='flag-5'>模式</b>的實例分析

    基于AT32(STM32)單片機的模塊化代碼之——按鍵代碼模塊化

    基于AT32(STM32)單片機的模塊化代碼之按鍵模塊化1.環境介紹平臺:AT32F415單片機,雅特力公司的AT32系列單片機其實跟STM32系列單片機大同小異,包括庫函數等基本都是一樣的,所以
    發表于 11-19 10:06 ?37次下載
    基于AT32(STM32)單片機的<b class='flag-5'>模塊化</b><b class='flag-5'>代碼</b>之——按鍵<b class='flag-5'>代碼</b><b class='flag-5'>模塊化</b>

    基于AT32(STM32)單片機的模塊化代碼之——ADC代碼模塊化

    基于AT32(STM32)單片機的模塊化代碼之——ADC代碼模塊化1.環境介紹平臺:AT32F415單片機,雅特力公司的AT32系列單片機其實跟STM32系列單片機大同小異,包括庫函數
    發表于 11-19 10:36 ?17次下載
    基于AT32(STM32)單片機的<b class='flag-5'>模塊化</b><b class='flag-5'>代碼</b>之——ADC<b class='flag-5'>代碼</b><b class='flag-5'>模塊化</b>

    設計模式行為型:觀察者模式

    定義對象之間的一種一對多依賴關系,使得每一個對象發生狀態的變化時,其相關依賴對象皆得到通知并被自動更新,又稱為發布-訂閱模式、模型-視圖模式、源-監聽器模式或從屬
    的頭像 發表于 06-07 16:56 ?713次閱讀
    設計<b class='flag-5'>模式</b>行為型:<b class='flag-5'>觀察者</b><b class='flag-5'>模式</b>

    觀察者模式,超詳細!

    觀察者模式建議你為發布類添加訂閱機制, 讓每個對象都能訂閱或取消訂閱發布事件流。 不要害怕! 這并不像聽上去那么復雜。 實際上, 該機制包括 1) 一個用于存儲訂閱
    的頭像 發表于 08-21 16:06 ?1281次閱讀
    <b class='flag-5'>觀察者</b><b class='flag-5'>模式</b>,超詳細!

    一文解析BLE觀察者模式回調機制

    nRF5 SDK從版本14開始,對事件回調機制做了更新,引入了觀察者模式,以解耦不同BLE Layer對BLE事件的回調函數。
    的頭像 發表于 11-27 10:07 ?1213次閱讀
    一文解析BLE<b class='flag-5'>觀察者</b><b class='flag-5'>模式</b>回調機制

    什么是觀察者設計模式?Golang中的觀察者模式介紹

    當涉及到訂單處理系統時,觀察者設計模式可以用于實現訂單狀態的變化和通知。
    的頭像 發表于 01-08 10:08 ?464次閱讀
    主站蜘蛛池模板: 日韩不卡毛片 | 久久免费看视频 | 苍井优一级毛片免费观看 | 午夜视频免费在线观看 | 婷婷6月 | www.欧美黄色 | 国模张文静啪啪私拍337p | 精品一区二区影院在线 | 香蕉视频色版在线观看 | 色香视频首页 | 狠狠天天| 狠狠色噜噜狠狠狠狠97 | 奇米激情| 美女露出尿口让男人桶爽网站 | 五月开心六月伊人色婷婷 | 亚洲国产毛片aaaaa无费看 | 色男人的天堂 | 午夜操操操| 国产精品爱啪在线线免费观看 | 色视频国产 | 成人欧美一区二区三区 | 亚洲最大成人综合网 | 在线视频亚洲一区 | 中文字幕一区在线播放 | 美女扒开尿口给男的桶个爽 | 成人5252色 | 免费a级毛片出奶水 | 四虎网站网址 | www.九色.com | 久久精品国产亚洲综合色 | 日日操夜夜操狠狠操 | 日本高清www | 在线天堂资源www中文在线 | 性xxxxbbbb免费播放视频 | aaaa级毛片| 欧美成人午夜不卡在线视频 | 天堂在线天堂最新版在线www | 4455ee日本高清免费观看 | 免费在线黄网站 | 日本欧美视频 | 亚洲一级毛片中文字幕 |