Dive into Spring framework -- 瞭解基本原理(一)

在繼續咱們的分析以前,推薦各位靜心來讀一下<<Expert_OneOne_J2EE_Design_and_Development>> 第四章, 正如spring BeanFactoryjava

API 中描述的。這一章主要說明了設計原則,設計模式,異常處理,反射等各個方面。原本也是想着直接來分析代碼,但咱們應該知其然也要知其因此然,爲了能加深理解Johnson建立框架的設計思路,就引入了這一部分。web

從spring的核心概念IoC入手,IoC的主要含義究竟是針對哪一個部分來講明的?是在xml配置的對象之間的關係麼?針對這個IoC,咱們應該如何應用?仍是應該看看spring究竟是怎麼應用的。spring

關於設計原則,比較推薦看看《敏捷軟件開發》,這裏面有最基本的設計原則的彙總,而expert書中都有不謀而合的理論。爲了全面,仍是結合了《敏捷》裏面的原則,主要羅列以下:設計模式

OCP(開閉原則)架構

在平常的開發分析過程當中,常常會遇到設計問題,咱們的框架須要知足任何需求的變動,設計模式裏面常常這樣來講明某個設計模式如何應對變化。可是全部的設計模式實際上都是建議咱們如何應對這樣的變化,應該如何考慮咱們的框架,因而按照《敏捷》裏面的定義:對擴展開放,對更改封閉。因此對於特定的需求設計,主要須要考慮的就變成了,如何來劃分擴展的部分和更改的部分。再也不重複《敏捷》裏面的例子,可是看完其Shape的例子,首先應該考慮的就是抽象,抽象就是咱們要找的擴展和更改的界限。框架

在接收到一個需求的時候,咱們能夠不顧一切的面向對象,直接寫出一些class,而後讓他們互相依賴,快速的完成這些功能。那麼接下來若是還有任何需求變動,就要直接修改那些類之間的依賴關係,這就如一個食物鏈,若是最底層的生物有什麼問題,那這條鏈子就會受影響,固然食物鏈這個類比有點牽強,畢竟一種生物不會一直吃一種食物,但咱們假設是那樣的。類之間的直接依賴相似於這樣的關係,若是咱們變了最底層的依賴,可能影響它的上層,上層也有可能進一步影響上層。若是像食物鏈那樣,每種生物有多種食物,也就是在處理依賴時,能給依賴多重選擇。應該如何來考慮這個「多重選擇」 , 固然應該是接口。《敏捷》在Shape示例中,由過程性代碼轉變成OO代碼,主要是加入了抽象,使得「引用」依賴接口中的「動做」,而並非「具體對象」。這是須要特別強調的,就是不要依賴對象,要依賴動做,而java裏面的interface就是「動做」的集合。spa


SRP(單一職責)設計

首先咱們要明確的是何爲職責,根據《敏捷》裏面的定義,「引發變化的緣由」。在平常開發裏面,這種情況太廣泛了,做爲開發大軍中的一員,就是這麼過來的,曾經有個action類能夠有3W行代碼。想一想這個代碼行數,就知道致使它發生變化的緣由多的很。若是(要是都有若是就行了)當年咱能頓悟出這麼幾個原則,就不說當年了,如今起就應該結合SRP和OCP來進行最初始的設計劃分。orm

通常的web應用項目,在action以後老是按照三層的概念實現底層,一個使用struts 1/struts2的項目老是會有比較雍容的action層,但service層卻僅僅是dao的封裝。因而一個貧血的架構就變得家喻戶曉。xml

但咱們常常忽略那些業務上的劃分,那麼結合框架和業務,應該如何來考慮這種劃分呢?首先一個action受http的影響(輸入和輸出),輸入參數的各類驗證,而後根據各類判斷來調用某個service。從總體架構上講,雖然是隔離了dao,但在業務層(action+service)會很臃腫。尤爲是action就是個定時炸彈,承擔各類職責。這個時候,就應該考慮一下設計模式來隔離一部分,劃分出變化的和不變的。


LSP(Liskov替換原則)

《敏捷》定義爲:子類型必須可以替換基類型。

這個定義裏面有着對繼承關係的強制性定義。其實在咱們的平常使用中,出現比較多的問題應該是,一個類繼承了不少沒用的功能,這可能是因爲沒有明確劃分功能範圍引發的接口方法污染。其實在一個子類不能徹底替換父類的時候,就應該引發咱們的警覺,是否應該按照SRP和OCP進行調整,LSP就像是一個標杆原則,老是要咱們檢驗繼承關係。


DIP(依賴注入)

《敏捷》認爲全部的依賴都不該該是直接的類依賴,而應該是基於抽象。這個跟《Expert》的Achieve Loose Couple with Interfaces的出發點是一致的。上層不該該直接依賴底層,而都應依賴抽象,這裏要強調兩個東西,一個是何爲抽象,一個是何爲依賴。抽象應該是動做的抽象,那就是接口。而依賴則不只僅是引用某個對象算是依賴,實現了某個接口也是一種依賴。


ISP(接口隔離)

在SRP的闡述中,就提及那個場景,咱們的一個類裏面可能不得不實現沒必要要的接口,這些上層接口的變化會影響實現類。在ISP中,就要求「不要強迫用戶依賴不使用的方法」。接口的劃分應該是基於業務須要的,若是一個interface中包含了幾個業務動做,那麼這不只僅不符合SRP的原則,同時給依賴方也帶來沒必要要的麻煩,那就是他們不得不實現不用的方法。出現這種狀況的時候,咱們應該考慮精細劃分客戶方的範圍,從而針對不一樣的客戶方,提供特別的接口動做。


以上主要是從《敏捷》中借鑑來的基本的設計原則,最開始的時候說過了,就是由於有殊途同歸的基礎,才考慮到直接引用《敏捷》的內容。在我看完《敏捷》以後的感受就是,這本書要一直伴隨個人左右,要深刻的實踐體會那些設計原則和模式。實際上這些原則都不能獨立的套用,而是相輔相成的。在上面的原則描述中,都基於一個最基本的基礎就是抽象。依賴抽象去實現OCP,如確認一種依賴以後,爲了之後的變化,上層依賴的是接口,而底層則多是經過策略模式等設計模式來開放給需求的變動,而這又偏偏是DIP所要求的。spring做爲使用如此普遍的框架,其設計必然符合這些基本原則,才能爲咱們提供那些不變的依賴,和咱們業務中變化的需求,那麼spring中的OO設計原則又特別強調哪幾個方面?


再次強調,《Expert》的chapter 4絕對值得讀5遍以上,這一章攤開來就能夠寫一本書,其中有一些引用資料,也極有參考價值。在寫這篇blog的時候,最開始特別想趕進度快點寫點東西,可是再來回味《Expert》卻發現之前那麼一些原則,在前幾年的開發裏面好像沒有多少顧忌的。因此就把這一章反覆讀了4遍,才略下本文,但願之後可以銘記和實踐。


下一部分看看spring的做者Rod Johnson是參考了哪些基本原則,考慮到哪些方面來實現了偉大的spring framework?

轉載請註明出處。 

相關文章
相關標籤/搜索