核心隱喻:托付式 vs. 警覺式
- 警覺式(輪詢):主動不斷檢查狀態 → 流程驅動編程。
- 托付式(通知):註冊回調,事件發生時被動響應 → 事件驅動編程(EDP)。
生活例證:推銷員主動拜訪(流程驅動)vs. 接線員等待來電(事件驅動);公車固定路線 vs. 計程車隨機載客。
事件分類
- 內建事件:
- 底層事件:硬體直接觸發(滑鼠移動、鍵盤按下)。
- 語義事件:組合底層事件表達業務邏輯(拖放 = 按下+移動+釋放)。
- 使用者自定義事件:封裝內建事件或純虛擬事件。
- 自然事件 vs. 合成事件:外部觸發 vs. 程式主動發射(模擬點擊)。
Win32 視窗程式四步驟
WinMain() {
// 1. 註冊視窗類別,指定回調函數 WndProc
windowClass.lpfnWndProc = WndProc;
RegisterClassEx(&windowClass);
// 2. 建立視窗
CreateWindowEx(..., windowClassName, ...);
// 3. 訊息迴圈
while (GetMessage(&msg, NULL, 0, 0) > 0) {
TranslateMessage(&msg);
DispatchMessage(&msg); // 分派至 WndProc
}
}
// 4. 視窗過程(事件處理器)
WndProc(..., msg, ...) {
switch (msg) {
case WM_SIZE: ...; break;
case WM_CLOSE: ...; break;
}
}
回調函數與控制反轉
回調機制
- 高層模組提供函數,低層庫函數間接調用 → 依賴反轉。
- 同步回調:傳入後立即執行(如
Arrays.sort 的 Comparator)。
- 異步回調:儲存起來,稍後事件觸發時調用(視窗程式)。
好萊塢原則
Don't call us, we'll call you. 框架掌握控制流,應用只填空白(實作介面/回調),實現控制反轉。
相關概念辨析
- IoC(控制反轉):框架調用應用代碼,降低耦合。
- DIP(依賴反轉原則):高層不依賴低層,雙方依賴抽象。
- DI(依賴注入):動態提供外部依賴。
- 三者核心:解耦,關鍵在抽象介面(現代術語取代舊稱「回調函數」)。
事件驅動三要素
- 實作事件處理器 / 監聽器。
- 註冊處理器至事件源。
- 實作事件迴圈(偵查、預處理、佇列、分派)。
主循環如心臟,處理器如大腦。IDE 常自動生成骨架與註冊代碼,但複雜系統仍需自行設計事件機制(定義、觸發、合併、調度、傳播、級聯等)。
異步機制與可伸縮性
- 阻塞調用:函數等待資源無法立即返回(如
socket.accept()),阻塞整個執行緒。
- 異步包裝:將耗時獨立操作移出主流程,完成後以事件通知重返。
- 前提:操作獨立(不佔用共享資源、不阻塞後續任務)。
- 理由:操作耗時。隨機性僅為副產品。
異步非阻塞減少資源浪費,提升效能與可伸縮性。
事件驅動模型與模式

- 事件源與處理器:動態註冊/註銷,鬆耦合多對多。
- 視角轉換:Client-Server(異步會話切換)↔ Peer-to-Pear(角色互換)。
- QQ 聊天 = P2P 事件驅動;電話 = 同步阻塞。
觀察者模式關係
- 觀察者 = 發布/訂閱 = 簡化的事件驅動(無事件管理器,源直接調用處理器)。
- MVC 為觀察者模式經典應用(Model 發布變更,View 訂閱更新)。
總結
- 事件驅動核心特徵:被動性(IoC)與異步性(會話切換)。
- 適用場景:GUI、網路伺服器、中介軟體、即時系統、高併發服務。
- 設計關鍵:識別阻塞調用、封裝為異步事件、善用框架 IoC 容器。