這里不得不說《冒號課堂——編程范式與OOP思想》真是一本好書,之前已經看過一遍。這幾天讀Spring源碼,發現Spring經常用到回調,對這個概念有些模糊了,於是把這本書翻出來看,算是溫故知新。
事件驅動式模型
事件是程序中令人關注的信息狀態上的變化。在基於事件驅動的系統中,事件包括內建事件與用戶自定義事件,其中內建事件又分為底層事件和語義事件。此外,事件還有自然事件與合成事件之分。
上圖是典型的事件驅動模型。事件處理器事先在關注的事件源上注冊,事件源不定期地發表事件對象,經過事件管理器的轉化(translate)、合並(coalesce)、排隊(enqueue)、分派(dispatch)等集中處理后,事件處理器接收到事件並對其進行相應處理。事件處理器隨時可以注冊或注銷事件源,意味着事件處理器和事件源之間的關系是動態建立和解除的。通過事件機制,事件源與事件處理器之間建立了松耦合的多對多關系:一個事件源可以有多個處理器,一個處理器可以監聽多個事件源。再換個角度,把事件處理器視為服務方,事件源視為客戶方,便是一個client-server 模式。每個服務方與其客戶方之間的會話(session)是異步的,即在處理完一個客戶的請求后不必等待下一請求,隨時可切換(switch)到對其他客戶的服務。更有甚者,事件處理器也能產生事件,實現處理器接口的事件源也能處理事件,它們可以角色換位,於是又演化為peer-to-peer模式。發行/訂閱模式(publish-subscribe pattern)正是觀察者模式(observer pattern)的別名,一方面可看作簡化或退化的事件驅動式,另一方面可看作事件驅動式的核心思想。該模式省略了事件管理器部分,由事件源直接調用事件處理器的接口。這樣更加簡明易用,但威力有所削弱,缺少事件管理、事件連帶等機制。著名的MVC(Model-View-Controller)架構正是它在架構設計上的一個應用。
回調
Callback指能作為參數傳遞的函數或代碼,它允許低層模塊調用高層模塊,使調用者與被調者從代碼上解耦。異步callback在傳入后並不立即被調用,使調用者與被調者從時間上解耦。
控制反轉一般通過callback來實現,其目的是降低模塊之間的依賴性,從而降低模塊的耦合度和復雜度。在框架設計中,控制反轉增強了軟件的可重用性、柔韌性和可擴展性,減少了用戶的負擔,簡化了用戶的代碼。控制反轉、依賴反轉原則和依賴注射是近義詞,它們的主題是控制與依賴,目的是解耦,方法是反轉,而實現這一切的關鍵是抽象接口。