C语言 串口通知消息,编程模式·观察者模式、事件通知、消息队列三者区别
觀察者模式、事件通知、消息隊(duì)列三者有類似,都有回調(diào)函數(shù)注冊(cè),通知調(diào)用的設(shè)計(jì),容易混淆。
簡述和區(qū)別
觀察者模式:被觀察對(duì)象狀態(tài)改變,所有觀察它的對(duì)象得到通知。也稱訂閱模式,英文Observer。
被觀察者不依賴觀察者,通過依賴注入達(dá)到控制反轉(zhuǎn)。
事件通知:事件發(fā)生后,通知所有關(guān)心這個(gè)事件的對(duì)象。
與觀察者模式對(duì)比,可理解成所有對(duì)象都只依賴事件系統(tǒng)。一半對(duì)象觀察事件系統(tǒng),等待特定通知;一半對(duì)象狀態(tài)變化就通過事件系統(tǒng)發(fā)出事件。
觀察者也不依賴被觀察對(duì)象,他只關(guān)心事件,不需要到被觀察對(duì)象那兒注冊(cè)自己。
被觀察者也只是普通對(duì)象,狀態(tài)改變,通過事件系統(tǒng)發(fā)出事件就行了。
消息隊(duì)列:將消息排成隊(duì)列,逐步分發(fā)通知。
與事件通知對(duì)比,可理解成事件不是立即通知,而是保存到隊(duì)列里,稍后通知。
這個(gè)可以達(dá)到時(shí)間解耦的效果。Windows的消息循環(huán)就是一個(gè)應(yīng)用。多線程情況下,消息隊(duì)列優(yōu)先于事件系統(tǒng)。
觀察者模式
以上課鈴聲為例子。上課鈴聲響,同學(xué)們回教室。
1. 簡單寫法
class 上課鈴{
function 響()
for 學(xué)生 in 學(xué)生們 do
學(xué)生->回教室()
end
end
}
這樣寫有問題:
上課鈴主動(dòng)通知學(xué)生回教室,依賴關(guān)系反了。
上課鈴響,老師要來上課,這個(gè)也得上課鈴?fù)ㄖ?#xff0c;上課鈴管的東西太多了。
2. 輪詢
class 學(xué)生{
function update()
if 上課玲響 then
回教室()
end
end
}
這樣上課鈴只管按時(shí)響就行了,也有問題:
學(xué)生的update會(huì)越來越復(fù)雜,學(xué)生還有很多其他事情要做呢。
update太耗時(shí)了,學(xué)生們,要精神緊張地仔細(xì)停玲聲有沒有響起。
3. 用觀察者模式
class 上課鈴: Subject{
function 響()
NotifyObservers()
end
}
class 學(xué)生: Observer{
function init()
上課玲->AddObserver(this.回教室)
end
function 回教室() ... end
function un_init()
上課玲->RemoveObserver(this.回教室)
end
}
這樣,上課鈴只要響的時(shí)候發(fā)個(gè)通知,學(xué)生們就等通知好了。老師也類似,等通知就行了。
小結(jié)
實(shí)際就是注冊(cè)個(gè)回調(diào)函數(shù),完美的將觀察對(duì)象和被觀察對(duì)象分離。
個(gè)人理解:依賴注入,控制反轉(zhuǎn)。觀察者依賴被觀察者,而不是被觀察者依賴觀察者。
事件系統(tǒng)
觀察者模式有兩個(gè)問題:
觀察者要獲得被觀察對(duì)象,然后才能注冊(cè)。
有時(shí)只是要知道某個(gè)事件發(fā)生了而已,類似網(wǎng)絡(luò)初始化好了的事件,并不需要獲得網(wǎng)絡(luò)管理對(duì)象。
觀察者和被觀察者要繼承對(duì)象的,在單繼承體系里,這是很昂貴的一件事。
上課鈴的例子里,學(xué)生只關(guān)心鈴聲,不關(guān)心上課鈴這個(gè)物體。
用事件模式就可以換個(gè)寫法
class 事件系統(tǒng){
function register(事件類型, handle);
function remove(事件類型, handle);
function trigger(事件類型, 數(shù)據(jù));
}
class 上課鈴{
function 響()
事件系統(tǒng)->trigger("上課鈴聲")
end
}
class 學(xué)生{
function init()
事件系統(tǒng)->register("上課鈴聲", this->回教室)
end
function 回教室() ... end
function un_init()
事件系統(tǒng)->remove("上課鈴聲", this.回教室)
end
}
小結(jié)
事件通知系統(tǒng)用的很廣泛的。很多代碼會(huì)有個(gè)EventDispatcher、EventControl之類的類。
特別是UI程序,當(dāng)數(shù)據(jù)發(fā)生變化時(shí)通知相關(guān)UI更新。
觀察者模式可以做到,但是事件通知來實(shí)現(xiàn)會(huì)更加簡單。
消息隊(duì)列
消息隊(duì)列和事件系統(tǒng)很像。但是消息隊(duì)列不是立即通知,而是把消息先放到隊(duì)列里再通知。
上課鈴的例子
class 消息隊(duì)列{
function register(消息類型, handle);
function remove(消息類型, handle);
function sendMsg(消息);
function process();
}
class 上課鈴{
function 響()
消息隊(duì)列->sendMsg("上課鈴聲")
end
}
class 學(xué)生{
function init()
消息隊(duì)列->register("上課鈴聲", this->回教室)
end
function 回教室() ... end
function un_init()
消息隊(duì)列->remove("上課鈴聲", this.回教室)
end
}
main{
while(有消息) do
消息隊(duì)列->process()
end
}
從偽代碼也可以看出,消息隊(duì)列和事件系統(tǒng)的使用基本是一樣的。如果消息隊(duì)列不延后處理,就是事件系統(tǒng)了。
消息隊(duì)列可以用于多線程,接受處理消息的handle們?cè)谥骶€程里。發(fā)送消息的可以在其他線程里。
簡單總結(jié)
需要分層解耦就用事件通知系統(tǒng)。
需要時(shí)間解耦就用消息隊(duì)列
總結(jié)
以上是生活随笔為你收集整理的C语言 串口通知消息,编程模式·观察者模式、事件通知、消息队列三者区别的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阴阳师茨球是什么 阴阳师茨球有什么用
- 下一篇: 回退n帧协议c语言代码,[计算机网络]C