一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

一文解析BLE觀察者模式回調(diào)機(jī)制

魚(yú)鷹談單片機(jī) ? 來(lái)源:魚(yú)鷹談單片機(jī) ? 2023-11-27 10:07 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

nRF5 SDK從版本14開(kāi)始,對(duì)事件回調(diào)機(jī)制做了更新,引入了觀察者模式,以解耦不同BLE Layer對(duì)BLE事件的回調(diào)函數(shù)。

實(shí)現(xiàn)這套機(jī)制用到了Flash的段(Section),將RAM中的函數(shù)調(diào)用與Flash中的段操作結(jié)合到一起,這個(gè)想法很新穎。

本文嘗試?yán)斫夂妥粉櫿麄€(gè)回調(diào)過(guò)程,并寫(xiě)一段代碼驗(yàn)證我們的思路。

一、觀察者模式簡(jiǎn)介

面向?qū)ο?a href="http://www.www27dydycom.cn/v/tag/1315/" target="_blank">編程世界里有許多著名的設(shè)計(jì)模式,其中一種叫觀察者模式,它解決的問(wèn)題是:在某場(chǎng)景下對(duì)象之間存在一對(duì)多的依賴關(guān)系,當(dāng)中心對(duì)象的狀態(tài)發(fā)生改變,其他所有依賴于它的對(duì)象都能得到通知并自動(dòng)更新。

04dbb3aa-8c54-11ee-939d-92fbcf53809c.png

觀察者模式中有幾種角色:觀察者(Observer),主題(Subject)和發(fā)布者(Publisher)。

多個(gè)觀察者可以獨(dú)立的訂閱(Subscribe)一個(gè)主題,當(dāng)該主題收到發(fā)布者推送的數(shù)據(jù),將數(shù)據(jù)通知(Notify)給各個(gè)觀察者進(jìn)行后續(xù)處理。

實(shí)現(xiàn)觀察者模式,觀察者端需要實(shí)現(xiàn)一個(gè)訂閱功能,將自己的句柄和回調(diào)函數(shù)傳遞給主題。主機(jī)端應(yīng)該有一個(gè)列表,所有訂閱它的觀察者句柄和回調(diào)函數(shù)都保存在該列表中,當(dāng)需要通知時(shí),則遍歷列表中的各個(gè)句柄,分別執(zhí)行各自的回調(diào)函數(shù)。發(fā)布者給主題發(fā)數(shù)據(jù),則簡(jiǎn)單的暴露一個(gè)接口即可。

更進(jìn)一步的,在代碼中要將句柄和回調(diào)函數(shù)封裝成一個(gè)結(jié)構(gòu)體,這樣就可以方便傳參。觀察者準(zhǔn)備一個(gè)函數(shù),將該結(jié)構(gòu)體保存到一個(gè)列表中,這個(gè)函數(shù)稱為訂閱。主題準(zhǔn)備一個(gè)函數(shù),讀取該列表,遍歷獲得各個(gè)結(jié)構(gòu)體,并執(zhí)行回調(diào),這個(gè)函數(shù)稱為通知。

設(shè)計(jì)這個(gè)列表是關(guān)鍵。

04f2c82e-8c54-11ee-939d-92fbcf53809c.png

最簡(jiǎn)單的辦法是準(zhǔn)備一個(gè)內(nèi)存數(shù)組,訂閱函數(shù)即寫(xiě)數(shù)組,通知函數(shù)即讀數(shù)組。

nRF5 SDK選擇了另一種方式,使用Flash的段。

二、Flash段簡(jiǎn)介

本文使用SEGGER Embedded Studio開(kāi)發(fā)工具進(jìn)行介紹,它后端使用arm gcc編譯器,需要用到它的鏈接文件(.ld)和map文件(.map)。

Flash的段是指在Flash中指定一塊空間,包含首地址和空間長(zhǎng)度,并設(shè)定一個(gè)段名。段名以點(diǎn)(.)開(kāi)頭。

C語(yǔ)言開(kāi)發(fā)中經(jīng)常提及的段有代碼段.text,常量段.rodata等。

04ff3c1c-8c54-11ee-939d-92fbcf53809c.png

利用__attribute__關(guān)鍵字,可以為變量指定段名,以下代碼將變量my_var存放在段.my_section中:

static my_type_t my_var __attribute__ ((section(".my_section"))) __attribute__((used)) = 
{
    .handler    = handler,
    .p_context  = NULL
};

還需要在內(nèi)存布局文件中,設(shè)定好該段的起始地址和長(zhǎng)度。編譯SES工程,將生成鏈接文件(.ld),可以看到諸如以下代碼:

.sdh_ble_observers ALIGN(__pwr_mgmt_data_end__ , 4) : AT(ALIGN(__pwr_mgmt_data_end__ , 4))
{
__sdh_ble_observers_start__ = .;
__start_sdh_ble_observers =   __sdh_ble_observers_start__;
KEEP(*(SORT(.sdh_ble_observers*)))
}
__sdh_ble_observers_end__ = __sdh_ble_observers_start__ + SIZEOF(.sdh_ble_observers);
__sdh_ble_observers_size__ = SIZEOF(.sdh_ble_observers);

其中xx_start__表示起始地址, xx_size__表示長(zhǎng)度,xx_end__表示結(jié)束地址。

注意到一個(gè)關(guān)鍵行:KEEP(*(SORT(.sdh_ble_observers*)))。

該行使用了通配符,.sdh_ble_observers*末尾的星號(hào)表示任意字符,所以我們可能在代碼中看到形如.sdh_ble_observers1這種段名。SORT表示將這些通配符所匹配的段按名稱增序排列。

查看map文件,可以看到如下記錄:

.sdh_ble_observers
                0x0000000000030ae4       0x30
                0x0000000000030ae4                __sdh_ble_observers_start__ = .
                0x0000000000030ae4                __start_sdh_ble_observers = __sdh_ble_observers_start__
 *(SORT_BY_NAME(.sdh_ble_observers*))
 .sdh_ble_observers0
                0x0000000000030ae4        0x8 Output/ble_app_blinky_pca10040_s132 Debug/Obj/ble_conn_state.o
 .sdh_ble_observers1
                0x0000000000030aec        0x8 Output/ble_app_blinky_pca10040_s132 Debug/Obj/main.o
 .sdh_ble_observers1
                0x0000000000030af4        0x8 Output/ble_app_blinky_pca10040_s132 Debug/Obj/ble_conn_params.o
 .sdh_ble_observers2
                0x0000000000030afc       0x10 Output/ble_app_blinky_pca10040_s132 Debug/Obj/main.o

在map文件中,我們看到了多個(gè)名字相似的段.sdh_ble_observers[0, 1, 2],它們擺列在一起,F(xiàn)lash地址前后相接,并且它們長(zhǎng)度之和等于.sdh_ble_observers段長(zhǎng)度。

可以認(rèn)為.sdh_ble_observers*是 .sdh_ble_observers的子段。

如何獲取段內(nèi)的數(shù)據(jù)呢?

一個(gè)是直接調(diào)用變量名,比如上面的my_var,另一種是通過(guò)段名,索引出其中的子段內(nèi)容。SDK中提供了段操作的函數(shù)庫(kù)nrf_section_iter, 如果已知一個(gè)段名,可以利用以下代碼獲取其中的子段內(nèi)容:

nrf_section_iter_t  iter;
for (nrf_section_iter_init(&iter, &my_section);
        nrf_section_iter_get(&iter) != NULL;
        nrf_section_iter_next(&iter))
{
    my_type_t     * p_section;
    p_section = (my_type_t*)nrf_section_iter_get(&iter);
}

三、BLE事件回調(diào)

以SDK15.1/ble_app_blinky工程為例, 追蹤它的BLE回調(diào)事件的調(diào)用邏輯。

在main.c –> ble_stack_init()中,調(diào)用了:

NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);

其中ble_evt_handler是我們?cè)O(shè)定的BLE事件回調(diào)函數(shù)。

NRF_SDH_BLE_OBSERVER是一個(gè)異常復(fù)雜嵌套宏,經(jīng)過(guò)層層解剖,該代碼變成如下形式:

static nrf_sdh_ble_evt_observer_t m_ble_observer __attribute__ ((section(".sdh_ble_observers3"))) __attribute__((used)) =
{
    .handler    =ble_evt_handler,
    .p_context  = NULL
};

這個(gè)代碼在 .sdh_ble_observers3 段中定義一個(gè)結(jié)構(gòu)體變量,并且將回調(diào)函數(shù)設(shè)定為參數(shù)。

那ble_evt_handler()是在什么地方調(diào)用的呢?

找到nrf_sdh_ble.c -> nrf_sdh_ble_evts_poll(),看見(jiàn)關(guān)鍵代碼:

nrf_section_iter_t  iter;
for (nrf_section_iter_init(&iter, &sdh_ble_observers);
        nrf_section_iter_get(&iter) != NULL;
        nrf_section_iter_next(&iter))
{
    nrf_sdh_ble_evt_observer_t * p_observer;
    nrf_sdh_ble_evt_handler_t    handler;


    p_observer = (nrf_sdh_ble_evt_observer_t *)nrf_section_iter_get(&iter);
    handler    = p_observer->handler;


    handler(p_ble_evt, p_observer->p_context);
}

這正是我們上面分析的,通過(guò)段名來(lái)獲取所有的子段內(nèi)容,然后執(zhí)行其回調(diào)函數(shù)。

仍然在該文件中,進(jìn)一步找到關(guān)鍵代碼:

NRF_SDH_STACK_OBSERVER(m_nrf_sdh_ble_evts_poll, NRF_SDH_BLE_STACK_OBSERVER_PRIO) =
{
    .handler   = nrf_sdh_ble_evts_poll,
    .p_context = NULL,
};

與上面類似,這是個(gè)嵌套宏,經(jīng)過(guò)層層解剖,得到如下代碼:

static nrf_sdh_stack_observer_t m_nrf_sdh_ble_evts_poll __attribute__ ((section(".sdh_stack_observers2"))) __attribute__((used)) =
{
    .handler    =nrf_sdh_ble_evts_poll,
    .p_context  = NULL
};

那 nrf_sdh_ble_evts_poll()是在什么地方調(diào)用的呢?

找到nrf_sdh.c -> nrf_sdh_evts_poll(),看見(jiàn)關(guān)鍵代碼:

for (nrf_section_iter_init(&iter, &sdh_stack_observers);
        nrf_section_iter_get(&iter) != NULL;
        nrf_section_iter_next(&iter))
{
    nrf_sdh_stack_observer_t    * p_observer;
    nrf_sdh_stack_evt_handler_t   handler;


    p_observer = (nrf_sdh_stack_observer_t *) nrf_section_iter_get(&iter);
    handler    = p_observer->handler;


    handler(p_observer->p_context);
}

進(jìn)一步,看到該函數(shù)的調(diào)用地點(diǎn):

void SD_EVT_IRQHandler(void)
{
    nrf_sdh_evts_poll();
}

SD_EVT_IRQHandler是BLE事件的中斷處理函數(shù),一旦芯片產(chǎn)生BLE事件,都會(huì)進(jìn)入到這個(gè)中斷處理函數(shù)中。按照上面的追蹤思路反向推導(dǎo),就能夠調(diào)用到最初的ble_evt_handler回調(diào)函數(shù)。

至此我們搞清楚了BLE事件回調(diào)的跳轉(zhuǎn)邏輯。

四、幾處細(xì)節(jié)

(1)SD_EVT_IRQHandler 是什么

它是BLE事件中斷。

經(jīng)過(guò)多次重定義跳轉(zhuǎn),我們找到它最初的名字:SWI2_EGU2_IRQHandler。

在ses_startup_nrf52.s文件中,看出它是一個(gè)中斷向量:

/* External Interrupts */
  .word   POWER_CLOCK_IRQHandler
  .word   RADIO_IRQHandler
  .word   UARTE0_UART0_IRQHandler
// ....
  .word   COMP_LPCOMP_IRQHandler
  .word   SWI0_EGU0_IRQHandler
  .word   SWI1_EGU1_IRQHandler
  .word   SWI2_EGU2_IRQHandler
  .word   SWI3_EGU3_IRQHandler

為什么它就代表了BLE的事件中斷呢?

在芯片手冊(cè)的Memory章節(jié),找到Instantiation小節(jié),列出了全部的中斷向量地址:

051366c4-8c54-11ee-939d-92fbcf53809c.png

比較這個(gè)列表與上面的中斷向量定義,發(fā)現(xiàn)它們是一一對(duì)應(yīng),嚴(yán)格按順序排列的。所以排到SWI2_EGU2_IRQHandler所在的位置,就代表了SWI2和EGU2的中斷向量,無(wú)論它取什么名字。

注意,SWI2和EGU2使用了同樣的向量地址,所以它們共享一個(gè)中斷向量,于是向量名稱寫(xiě)成SWI2_EGU2_IRQHandler。

(2)為什么要索引兩次

在nrf_sdh_evts_poll函數(shù)中,調(diào)用了 nrf_sdh_ble_evts_poll(),然后再調(diào)用我們的ble_evt_handler,為什么要索引兩次呢?

仔細(xì)看代碼發(fā)現(xiàn),nrf_sdh_evts_poll處理了BLE和SOC兩種事件。而ble_evt_handler只是BLE事件。

這是因?yàn)镾WI2和EGU2這二者共享一個(gè)中斷向量,它們出了給出BLE事件中斷,還會(huì)給出SOC相關(guān)的中斷,比如時(shí)鐘Clock等。

(3)APP_BLE_OBSERVER_PRIO是什么

它代表了優(yōu)先級(jí)。

前面提到.ld文件中使用了SORT對(duì)所有子段進(jìn)行增序排列,優(yōu)先級(jí)數(shù)值小的排前面,大的排后面,在索引子段內(nèi)容時(shí)候,總是先執(zhí)行高優(yōu)先級(jí)(數(shù)值?。┑幕卣{(diào)函數(shù),后執(zhí)行低優(yōu)先級(jí)(數(shù)值大)的回調(diào)函數(shù),相同優(yōu)先級(jí)的回調(diào)則不能確定執(zhí)行順序。

(4)觀察者角色

在上面的分析中,NRF_SDH_BLE_OBSERVER意味著訂閱函數(shù),main.c中的BLE處理相當(dāng)于一個(gè)觀察者。

SDK中將訂閱函數(shù)進(jìn)一步封裝成BLE_XXX_DEF()的宏形式,比如GATT的訂閱函數(shù)宏:

NRF_BLE_GATT_DEF(_name)

許多BLE庫(kù)都提供了訂閱函數(shù)宏,使用時(shí)候只需在main.c中聲明它們。

BLE通用訂閱函數(shù)宏:
#define BLE_ADVERTISING_DEF(_name)
#define BLE_DB_DISCOVERY_DEF(_name)
#define BLE_LINK_CTX_MANAGER_DEF()
#define NRF_BLE_SCAN_DEF(_name)
#define NRF_BLE_GATT_DEF(_name)
#define NRF_BLE_QWR_DEF(_name)


BLE Profile訂閱函數(shù)宏:
#define BLE_BAS_DEF(_name)
#define BLE_BPS_DEF(_name)
#define BLE_CSCS_DEF(_name)
#define BLE_GLS_DEF(_name)
#define BLE_HIDS_DEF()
#define BLE_HRS_DEF(_name)
#define BLE_HTS_DEF(_name)
#define BLE_LBS_DEF(_name)
...

如果我們創(chuàng)建一個(gè)自定義的Profile,也應(yīng)該提供一個(gè)這樣的訂閱函數(shù)宏。

nrf_sdh_ble_evts_poll和nrf_sdh_evts_poll相當(dāng)于通知函數(shù),nrf_sdh.c和nrf_sdh_ble.c充當(dāng)主題角色。

發(fā)布者是芯片, SD_EVT_IRQHandler中斷就是發(fā)布者向主題推送數(shù)據(jù)接口。

五、驗(yàn)證

嘗試寫(xiě)一段代碼,驗(yàn)證這種段操作的觀察者模式。

先定義一個(gè)段:syq_sections

typedef void (*syq_handler_t)(uint8_t const evt_code, void * p_context);


typedef struct
{
    syq_handler_t         handler;      //!< BLE event handler.
    void *                p_context;    //!< A parameter to the event handler.
} const syq_type_t;


NRF_SECTION_SET_DEF(syq_sections, syq_type_t, NRF_SDH_BLE_OBSERVER_PRIO_LEVELS);

設(shè)定三個(gè)不同優(yōu)先級(jí)的段變量:

void syq_handler1(uint8_t const evt_code, void * p_context)
{
    NRF_LOG_INFO("handler1 is triggered");
}


static syq_type_t m_syq_1 __attribute__ ((section(".syq_sections1"))) __attribute__((used)) = 
{
    .handler    = syq_handler1,
    .p_context  = NULL
};


void syq_handler2(uint8_t const evt_code, void * p_context)
{
    NRF_LOG_INFO("handler2 is triggered");
}


static syq_type_t m_syq_2 __attribute__ ((section(".syq_sections2"))) __attribute__((used)) = 
{
    .handler    = syq_handler2,
    .p_context  = NULL
};


void syq_handler3(uint8_t const evt_code, void * p_context)
{
    NRF_LOG_INFO("handler3 is triggered");
}


static syq_type_t m_syq_3 __attribute__ ((section(".syq_sections3"))) __attribute__((used)) = 
{
    .handler    = syq_handler3,
    .p_context  = NULL
};

在主函數(shù)中執(zhí)行索引:

nrf_section_iter_t  iter;
for (nrf_section_iter_init(&iter, &syq_sections);
        nrf_section_iter_get(&iter) != NULL;
        nrf_section_iter_next(&iter)) {
    syq_type_t * p_observer;
    syq_handler_t    handler;


    p_observer = (syq_type_t *)nrf_section_iter_get(&iter);
    handler    = p_observer->handler;


    handler(1, p_observer->p_context);
}

這樣就可以依次執(zhí)行三個(gè)不同優(yōu)先級(jí)的回調(diào)函數(shù),打印結(jié)果如下:

0527ebd0-8c54-11ee-939d-92fbcf53809c.png

利用這套做法,實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的觀察者模式。






審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • FlaSh
    +關(guān)注

    關(guān)注

    10

    文章

    1673

    瀏覽量

    151334
  • C語(yǔ)言
    +關(guān)注

    關(guān)注

    180

    文章

    7630

    瀏覽量

    140970
  • BLE
    BLE
    +關(guān)注

    關(guān)注

    12

    文章

    697

    瀏覽量

    60560
  • 回調(diào)函數(shù)
    +關(guān)注

    關(guān)注

    0

    文章

    88

    瀏覽量

    11861
  • gcc編譯器
    +關(guān)注

    關(guān)注

    0

    文章

    78

    瀏覽量

    3694

原文標(biāo)題:BLE 觀察者模式回調(diào)機(jī)制解析

文章出處:【微信號(hào):emOsprey,微信公眾號(hào):魚(yú)鷹談單片機(jī)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    詳解調(diào)機(jī)制的實(shí)現(xiàn)

    軟件模塊之間總是存在著定的接口,從調(diào)用方式上,可以把他們分為三類:同步調(diào)用、調(diào)和異步調(diào)用。同步調(diào)用是種阻塞式調(diào)用,調(diào)用方要等待對(duì)方執(zhí)行完畢才返回,它是種單向調(diào)用;
    發(fā)表于 08-02 06:04

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

    希望個(gè)CC2540先通過(guò)觀察者角色獲取其他廣播的廣播數(shù)據(jù),然后在切換為廣播角色將這些數(shù)據(jù)廣播給另外個(gè)
    發(fā)表于 03-16 10:27

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

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

    屬性觀察者的特點(diǎn)

    。 2,給屬性添加觀察者必須要聲明清楚屬性類型,否則編譯器報(bào)錯(cuò)。 3,willSet可以帶個(gè)newName的參數(shù),沒(méi)有的話,該參數(shù)默認(rèn)命名為newValue。 4,didSet可以帶個(gè)
    發(fā)表于 11-04 07:10

    觀察者模式在嵌入式編程設(shè)計(jì)中有何作用

    觀察者模式是最常見(jiàn)的模式。這種模式提供種方法來(lái)時(shí)對(duì)象“監(jiān)聽(tīng)”其他對(duì)象,而不需要修改任何數(shù)據(jù)
    發(fā)表于 12-22 08:31

    基于觀察者模式的屏幕布局控件設(shè)計(jì)

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

    Java設(shè)計(jì)模式分析之觀察者

    觀察者模式的流程跟報(bào)紙訂閱方式致,即:觀察者模式=出版+訂閱
    發(fā)表于 09-26 17:36 ?0次下載

    詳解java 調(diào)機(jī)制

    代碼示例 接下來(lái)看一下回調(diào)的代碼示例,代碼模擬的是這樣種場(chǎng)景:老師問(wèn)學(xué)生問(wèn)題,學(xué)生思考完畢回答老師。 首先定義個(gè)
    發(fā)表于 09-28 13:14 ?0次下載

    在 Java8 環(huán)境下實(shí)現(xiàn)觀察者模式的實(shí)例分析

    個(gè)組成部分。目前雖然已經(jīng)有大量關(guān)于觀察者模式的文章,但它們都專注于在 Java 中的實(shí)現(xiàn),卻忽視了開(kāi)發(fā)在Java中使用觀察者
    發(fā)表于 10-12 16:09 ?0次下載
    在 Java8 環(huán)境下實(shí)現(xiàn)<b class='flag-5'>觀察者</b><b class='flag-5'>模式</b>的實(shí)例分析

    根據(jù)調(diào)機(jī)制注冊(cè)事件并處理調(diào)VI

    通過(guò)事件調(diào)注冊(cè)函數(shù)(Register Event Callback)注冊(cè)個(gè)調(diào)VI,在事件發(fā)生時(shí)會(huì)運(yùn)行該回
    的頭像 發(fā)表于 11-24 09:15 ?2887次閱讀

    設(shè)計(jì)模式行為型:觀察者模式

    定義對(duì)象之間的對(duì)多依賴關(guān)系,使得每個(gè)對(duì)象發(fā)生狀態(tài)的變化時(shí),其相關(guān)依賴對(duì)象皆得到通知并被自動(dòng)更新,又稱為發(fā)布-訂閱模式、模型-視圖模式
    的頭像 發(fā)表于 06-07 16:56 ?874次閱讀
    設(shè)計(jì)<b class='flag-5'>模式</b>行為型:<b class='flag-5'>觀察者</b><b class='flag-5'>模式</b>

    觀察者模式,超詳細(xì)!

    觀察者模式建議你為發(fā)布類添加訂閱機(jī)制, 讓每個(gè)對(duì)象都能訂閱或取消訂閱發(fā)布事件流。 不要害怕! 這并不像聽(tīng)上去那么復(fù)雜。 實(shí)際上, 該
    的頭像 發(fā)表于 08-21 16:06 ?1597次閱讀
    <b class='flag-5'>觀察者</b><b class='flag-5'>模式</b>,超詳細(xì)!

    基于觀察者模式設(shè)計(jì)的框架-REB,使代碼模塊化

    設(shè)計(jì)模式里面的觀察者模式直是作者想去設(shè)計(jì)套框架來(lái)闡述這個(gè)
    的頭像 發(fā)表于 10-17 09:35 ?1026次閱讀
    基于<b class='flag-5'>觀察者</b><b class='flag-5'>模式</b>設(shè)計(jì)的框架-REB,使代碼模塊化

    什么是觀察者設(shè)計(jì)模式?Golang中的觀察者模式介紹

    當(dāng)涉及到訂單處理系統(tǒng)時(shí),觀察者設(shè)計(jì)模式可以用于實(shí)現(xiàn)訂單狀態(tài)的變化和通知。
    的頭像 發(fā)表于 01-08 10:08 ?651次閱讀

    基于藍(lán)牙模組Beacon+觀察者模式實(shí)現(xiàn)資產(chǎn)管理和室內(nèi)定位

    種廣播協(xié)議設(shè)備(從機(jī))。Beacon主要參數(shù)①uuid②major③minor④companyID觀察者模式1.用于監(jiān)聽(tīng)其他設(shè)備的廣播數(shù)據(jù)而不與之建立連接;2.
    的頭像 發(fā)表于 05-15 19:34 ?251次閱讀
    基于藍(lán)牙模組Beacon+<b class='flag-5'>觀察者</b><b class='flag-5'>模式</b>實(shí)現(xiàn)資產(chǎn)管理和室內(nèi)定位