本章重點
- 框架只是細節
- 框架並不等同於系統架構
- 框架作者的動機:框架作者通常是為了解決他們自己或周圍人的問題,並不一定適合你的需求。
- 風險
- 不對等的婚姻:使用框架時,你需要做出巨大的承諾,但框架作者對你沒有任何承諾。
- 解決方案
- 不要與框架耦合,保持一定距離,將框架視為架構外圈的一個細節。
一旦在專案中引入一個框架,很有可能在整個生命週期中都要依賴於它,不管後來情形怎麼變化,這個決定都很難更改了。
原文翻譯
應用程式框架現在非常流行,通常來說這是一件好事。許多框架都非常強大、實用,而且是免費的。
然而,框架並不等同於系統架構——儘管有些框架確實試圖成為系統架構。
框架作者
大部分框架的作者願意免費提供自己的工作成果,是因為他們想要幫助整個社群,想要回饋社會。這值得鼓勵,但不管這些作者的動機有多麼高尚,恐怕也沒有提供針對你個人的最佳方案。即使他們想,也做不到,因為他們並不了解你,也不了解你遇到的問題。
這些框架作者所了解的都是他們自己遇到的問題,可能還包括同事和朋友所遇到的。他們創造框架的目的是解決這些問題——而不是解決你遇到的問題。
當然,你所遇到的問題可能和其他人遇到的問題大致相同。如果不是這樣,框架也不會那麼流行。正是因為這種重合性的存在,框架才這麼有用。
嫁給框架-不對等的婚姻 (ASYMMETRIC MARRIAGE)
你和框架作者之間的關係是非常不對等的。你必須對框架做出巨大的承諾,但框架作者對你卻沒有任何承諾。
仔細想想這一點。當你使用一個框架時,你需要閱讀框架作者提供的文檔。在這些文檔中,框架作者和其他使用者會建議你如何將軟體與框架整合。通常,這意味著你需要將你的架構圍繞著框架來設計。作者會建議你從框架的基類派生,並將框架的功能引入到你的業務對象中。作者會敦促你盡可能緊密地將應用程式與框架結合。
此外,作者希望你與框架緊密結合,因為一旦這樣耦合,脫離框架就會變得非常困難。對框架作者來說,沒有什麼比一群用戶心甘情願地從作者的基類派生更令人滿意的了。
換句話說,框架作者想讓我們與框架訂終身——這相當於我們要對他們的框架做一個巨大而長期的承諾,而在任何情況下框架作者都不會對我們做出同樣的承諾。這種婚姻是單向的。我們要承擔所有的風險,而框架作者則沒有任何風險。
這是風險
那麼我們要承擔的風險究竟有哪些呢?我們可以想到的至少有以下這幾項:
框架本身的架構設計很多時候並不是特別正確的。框架本身可能經常違反依賴關係原則。譬如,框架可能會要求我們將代碼引入到業務對象中——甚至是業務實體中。框架可能會想要我們將框架耦合在最內圈代碼中。而我們一旦引入,就再也不會離開該框架了,這就像戴上結婚戒指一樣,從此一生不離不棄了。
框架可能會幫助我們實現一些應用程式的早期功能,但隨著產品的成熟,功能要求很可能超出框架所能提供的範圍。而且隨著時間的推移,我們也會發現在應用的開發過程中,自己與框架鬥爭的時間要比框架幫助我們的時間長得多。
框架本身可能朝著我們不需要的方向演進。也許我們會被迫升級到一個並不需要的新版本,甚至會發現自己之前所使用的舊功能突然消失了,或悄悄改變了行為。
未來我們可能會想要切換到一個更新、更好的框架上。
解決方案
解決方案是什麼呢?
請不要嫁給框架! (Don’t marry the framework!)
哦,你可以使用框架——但不要與它耦合。保持一定的距離。將框架視為架構外圈的一個細節,不要讓它進入內圈。
如果框架要求你根據它們的基類來創建派生類,就請不要這樣做!你可以創造一些代理類,並將這些代理類當作業務邏輯的插件來管理。
不要讓框架進入你的核心代碼。相反,應該依據依賴關係原則,將它們整合到作為核心代碼插件的組件中。
以 Spring 為例,它作為一個依賴注入框架是很不錯的,也許你會需要用 Spring 來自動連接應用程式中的各種依賴關係。這不要緊,但千萬別在業務對象裡到處寫 @autowired 註解。業務對象應該對 Spring 完全不知情才對。
相反,你可以利用 Spring 將依賴關係注入到 Main 組件中,畢竟 Main 組件作為系統架構中最低層、依賴最多的組件,它依賴於 Spring 並不是問題。
不得不接受的依賴
有一些框架是避免不了使用的。例如,如果你在用 C++,那麼 STL 就是很難避免使用的。如果你在用 Java,那麼標準類庫也是不太可能避免使用的。
這很正常——但這仍然應該是你主動選擇的結果。你必須明白,如果一旦在專案中引入一個框架,很有可能在整個生命週期中都要依賴於它,不管後來情形怎麼變化,這個決定都很難更改了。因此,不應該草率地做出決定。
本章小结
總而言之,當我們面臨框架選擇時,盡量不要草率地做出決定。在全身心投入之前,應該首先看看是否可以部分地採用以增加了解。另外,請盡可能長時間地將框架留在架構邊界之外,越久越好。因為誰知道呢,也許你可以不用買奶牛也能喝到牛奶。