事件、命令、信號、函數、方法
搞了這麽多年的技術,一直對 事件與命令、函數與方法的概念模糊不清。今天詳細記錄一下。
函數與方法
第一門語言學習的c語言,老師常說寫一個函數或者庫函數。
其實編程和數學密不可分,以數學為基礎的一門科學。
數學裏常見的函數 y = sin(x). 這是個sin叫函數,不是叫方法。
學c語言,寫一個函數,調用一個方法。
函數白話文的解釋就是一堆指令(某個步驟,可以包括方法)封裝成一個整體。
方法白話文的解釋就是使用函數。
比如常說用什麽方法解決某某問題。
解決某一類問題可以分裝成一個函數,如果向解決這個問題,直接調用這個函數就行。 調用這個函數也即使用這個方法。
總結:
在函數式編程的語言中 沒必要太過糾結這兩個概念。可以理解為就是一個意思。
比如c語言,lua, javascript 等等語言中沒有對象的概念,
在面向對象的語言中, 方法一般是指對象的行為。
比如經常有人問 某某類有哪些方法。 而不會問這個類有些函數。
函數強調功能定義,方法強調功能的使用。 當然函數中可以包括方法調用。
事件與命令與信號
理論:
事件是可以被控件識別的操作。事件有系統事件和用戶事件
命令形容在對計算機程序編程時所下達的編程指令。
信號是運載消息的工具,是消息的載體
白話文裏的事件:
常見的事件有 點擊事件,觸摸事件等等, 這些都是由於用戶點擊按鈕,之後生成的事件。
描述一個事件通常是
class event{
事件類型
事件發生時間
}
指的是某個事情發生了。後續產生什麽影響,制作事件的人是不知道的。
如果點擊了某個按鈕,用戶發了一個點擊事件,但是這個事件之後,是關機電腦,還是退出遊戲是不知道的。
正規的應用程序,一般在按鈕上表明,該按鈕事件之後的用途, 比如顯示一個QQ圖標,或者QQ登陸,用戶點擊一下,就登陸了。
非正規的應用程序,點擊QQ按鈕,可能後臺執行一個病毒。
總的來說,事件之後產生什麽影響或者說做什麽事情,由應用程序制作者定義。 事件之後沒有任何反應也是很有可能的,
現在很多APP,都有出現級個別按鈕點擊後無反應的情況。可能有bug也可能是開發人員太忙沒時間處理。
如果是給用戶用的,為了提高用戶體驗我覺得還是給一個用戶可以感知到的信息(彈窗或者刷新刷新數據之類的)為好。
白話文裏的命令:
常見的命令 ls, prep, find top 等等命令。 這些命令Linux操作系統提供。由操作系統執行。其實這些都是可執行程序。叫主命令,標識應用程序本身
還有一種叫子命令,標識具體動作。 這個動作可以是打印一句話,也可以播放一段視頻,或者調用其他打開其他應用,當然也可以啥都不做, 這個取決於應用設計本身。
一個通常會有一個help命令,或者有一個說明文檔,來告訴別人應用系統裏有哪些命令,已經如何使用。
在一個比較大軟件項目裏,也經常會設計一個這個命令系統。
比如svn軟件。 提供的命令有 ls 、add 、 rm 、help等等
描述一個命令通常是
class commad{
命令名
}
只有應用軟件才能認識
在函數式編程裏,命令模式通常是這樣的
switch(cmdName):{
case "rm": 做相應刪除事情
case "add": 做相應添加事情
....
}
在面對對象編程裏,命令模式通常是這樣的
class Command{
Cammad()
excute() = 0 // 抽象方法
}
class RmCommand 繼承 Command{
excute() {執行刪除的操作}
}
class AddCommand 繼承 Command{
excute() {執行添加的操作}
}
switch(cmdName):{
case "rm": rm.excute()
case "add": add.excutue()
....
}
區別
命令 主動性很強, 制作命令的人很清楚,要做什麽。 【即將發生】
事件 被動性很強。 生產事件的人不知道,接下來發生什麽。【已經發生】
相同點:
事件之後或者命令之後都是要做一些事情(當然也可以啥都不做)。
事件有事件隊列,事件不能撤銷,因為已經發生了。
命令有命令流, 命令可以撤銷。比如文本編輯器,可以撤銷更改
=====================================
信號:
說白了就是一個數據而已。
比如系統信號, kill -9 進程ID。 強制殺死某個進程。 這個殺死進程的時候,系統會先給這個進程發一個終止數據,然後在殺死。
應用程序收到信號會可以做保存數據的動作,或者其他動作。
也就是說執行某個動作前,先告知一下,然後在執行。有先兆性。
如果信號產生了,表示之後動作一定會執行。如果某某程序崩潰,系統會給這個程序發送崩潰信號,然後在關掉應用程序。
應用程序可以保存堆棧信息,以供分析什麽原因導致的崩潰。
操作系統是發送者, 應用程序是接收者。
軟件架構裏,有一個消息的概念, 其實和信號差不多,但是也有不同點。
發送消息可以任何時候任何代碼段都可以發送。 接收者可以是任何類或者其他系統(服務器或者其他應用進程)。
如程序啟動時發送一個消息。 結束運行發送消息。
發送消息的時候說明動作正在執行, 僅僅是做一個通知而已。 這個通知可以是命令,可以是事件,也可以其他數據。
消息的概念比信號的概念更廣, 網絡消息,內部消息, 層與層之間的消息,事件消息, 命令消息等等這些統稱為消息。
有發送者一般就有接收者,不然發消息毫無意義。
函數調用其實也是一種發送消息的一種體現,具體函數肯定是接收者, 發送者可以發生任何地方。 這個接收者是唯一的。這種耦合太緊了。
一般的軟件架構裏,發送者不知道接收者是誰,接收者也不知道發送者時,兩者解偶是有很多好處的。
實現這樣的模式有 觀察者模式,命令模式,消費者/生產者模型, 消息隊列(queue,redis,rabbitmq等),中介模式,都可以實現兩者解偶。
這些模式都有一個通用點就是有一個存儲消息的容器。只不過職責不一樣而已。搞設計不要太執迷於設計模式。
最簡單的lua 實現就是下面這樣。
local data = {}
function send(msg) table.insert(data,msg) end
function recv() dispatch(table.remove(data,1)) end
事件、命令、信號、函數、方法