在開發應用的過程中,會使用一些程式庫,例如,應用程式也許使用了 OWASP 的 HTML Sanitizer、H2 JDBC 驅動程式、Java Mail 等,然而,應用程式程式主要流程一直在你的控制之內,你決定了何時要處理請求參數、取得模型物件、轉發請求、顯示頁面等各式流程。
控制、熟悉應用程式的流程走向,是很重要的一部份,在打算套用框架之前,你必須先認清應用程式的流程走向,至少,你應該寫個原型,試著摸出、掌握大致的流程走向,這對後續框架的選擇、使用會有很大的幫助。
因為在開始使用框架之後,會發現框架將主導程式運行的某個流程,你必須在框架的規範下定義某些類別,框架會在適當時候調用你實作的程式元件,也就是說,對應用程式的流程控制權會被反轉,框架會規範、限制應用程式流程,框架會呼叫你的程式元件,而不是由你來呼叫框架。
例如,使用程式庫的話,主要流程的控制是這樣的:
灰色部份是可以自行掌控的流程,並在過程中必要時機,引用各種程式庫,當然,執行程式庫的過程中,會暫時進入程式庫的流程,不過,絕大多數的情況下,你對應用程式的主要流程,還是擁有很大的控制權。
使用框架的話,主要流程的控制是這樣的:
這就是控制權反轉(Inverse of Control, IoC)的解讀之一,使用框架的話必須注意,流程控制權會從你的手中反轉至框架身上!
當然,框架本質上也是個程式庫,不過會被定位為框架,表示它對程式主要流程擁有更多的控制權,然而,框架本身是個半成品,想要完成整個流程,必須在框架的流程規範下,實現自定義元件,如上圖表示的,灰色部份是可以自行掌控的部份,與使用程式庫相比,對流程控制的自由度少了許多。
應用程式開發時是否需要使用框架,有很多考量點,然而簡單來說,使用程式庫時,開發者會擁有較高的自由度;使用框架時,開發者會受到較大的限制。
若應用程式本身不複雜,不需要套用任何框架就可以完成這項任務,那麼就不要使用框架,因為若要使用框架,往往必須按照框架的規範實作定義檔、設定相關數值、依一定方式取得元件等,若應用程式本身並不複雜,在享用到框架的益處之前,就會被一堆繁瑣規範或設定給困擾,產生「有必要這麼複雜嗎?」的疑惑,若框架本身又很龐大,光是學習、掌握到熟練框架,也會付出很大的成本。
然而,如果應用程式在主要流程、組合元件甚至管理元件生命週期管理等需求上,自行撰寫程式碼完成任務已成沉重負擔之時,而框架對這些需求,若能大致符合既有之需求,套用框架可省去自行撰寫、維護元件生命週期等程式碼的麻煩,這時換取而來的益處超越了犧牲掉的流程自由度,才會使得使用框架具有意義。
類似地,想要套用 Spring MVC 之類的 Web 框架嗎?那要先問自己,應用程式打算遵照或已經是 MVC 流程架構了嗎?如果不是,那使用 Spring MVC 並不會為你帶來益處,反而會感到處處受限,正如股市有句名言:「好的老師帶你上天堂,不好的老師帶你住套房。」用框架時可以這麼想:「好的框架帶你上天堂,不好的框架帶你住套房。」
在程式設計相關的領域中,名詞多半沒有嚴謹的定義,這邊談到的 Inversion of Control,是在使用任何框架前必須要有的認知,然而,並不是 Spring IoC 核心中的 Inversion of Control 概念,由於經常有人將兩者混淆在一起,後來 Martin Fowler 建議使用 Dependency Injection 來取代 Spring 中 對 IoC 的稱呼。