標籤:架構設計 模組化 開發模式 讀書筆記
本書主要模組化模式的好處、模組化方法與模式、OSGi簡單使用等內容,分3大部分:
第一部分介紹了模組化概念,為什麼要模組化,以及一些模組化要考慮的東西,如模組粒度,依賴關係,重用性靈活性等。
第二部分介紹模組化的一些模式,採用了GoF設計模式的格式(模式名稱、模式表述、圖示、描述、多種實現、效果、範例、小結),看著有些亂,但是收穫不少。
第三部分介紹OGSi結合Java如何使用,以及如何模組化現有系統。Java中無法直接模組化(Java SE模組化功能Jigsaw被延遲到了Jave SE 9),因為你可以隨時訪問其他模組類中的任意public方法,想要強制性模組化,只允許訪問發布的方法,可以使用OSGi架構。
這裡模組化的概念和組件化相似,可部署、可管理、原生可重用、可組合、無狀態的軟體單元,對外提供了簡介的介面。在Java中,最適合模組化的單元就是Jar檔案。
代碼層面我們關注的太多了,熟練的開發人員現在很少爭論使用模式的好處,也不再識別哪個模式適合當前需要,因為都能夠本能地使用各種設計原則和模式,從GoF的設計模式到衍生出的設計原則,現在很多原則已經幾乎變成了本能,如“優先組合而不是繼承”、“面向抽象而不是面向實現”。
但是只考慮類層級的設計,那麼不管設計的多麼漂亮,都不會代碼預期的收益。因為現有的設計原則和物件導向開發模式不能協助管理大型軟體系統的複雜性,因為他們解決的是不同的問題。
架構的目標是儘可能減少變化的影響和成本。模組化通過填補高層架構組件以及底層代碼之間的空白,協助我們實現這個目標。
通用的原則:
1、介面要更接近使用它們的類,而遠離實現它們的類。
2、異常應該接近拋出它們的類或介面,而不是接近捕獲異常的模組
模組化的一些模式和方法,大體的思想原則和類設計的原則相似,很多方法都是基於“依賴抽象而非依賴實現”這個原則的。
1、悖論,粒度越小的模組越靈活,管理起來也就越複雜,如何在靈活性和管理複雜度兩者間取捨。最大化重用使得可用複雜化,粒度越小的模組重用性越高,可用性越低,也就是越不方便用,如何在重用性和可用性之間取捨。雖然沒有絕對的結論,但是大方向上有了結論。
2、穩定性,具有大量被依賴的模組應該是很穩定的,也就是很少發生變化,變化帶來的影響更大。確保模組穩定性最好的方式就是將其轉換為抽象模組。具有大量依賴其他模組的模組,是不穩定的,很容易進行變化,便於使用,但是不容易測試(因為依賴其他模組太多),最好的方式應該依賴抽象模組。
3、模組等級必須分等級,模組必須等級化,高等級依賴低等級,低等級不能依賴高等級,低等級不能有太多依賴,等級越低的模組應該越穩定,不穩定的模組應該放到高等級。
4、模組重用,類層級重用不能跨應用(比如工具類),而模組層級別重用可以跨應用。
軟體開發初期,需求處於不斷變化之中,模組粒度應該大,易於管理和使用。隨著識別出需求變化的重點,找出了可重用的地方,較大模組應該拆分成較小的、更易於重用的細粒度模組。軟體開發初期就試圖定義較小的細粒度模組是很困難的,因為只能猜測重用點在哪,通常是失敗的。
5、模組內聚:高內聚的模組易於理解、維護和重用。影響模組內聚的因素有2點,一個是類變化的頻率,另一個是類的可重用性。軟體開發初期應基於變化頻率構建模組,因為系統不穩定,系統穩定後,應基於重用構建模組。也就是說軟體前期很難建立高內聚的模組,隨著系統穩定,Team Dev應該重新組織系統以確保模組都是內聚的。
6、模組依賴,高等級模組單向依賴低等級模組是最好的,最不好的就是循環相依性,這裡提供幾個方法消除依賴。單向依賴時,比如低層級模組依賴高等級模組了,解決方案:反轉關係:穩定模組A依賴B的部分抽象介面,依賴自己介面,B去實現這個介面,達到B依賴A的反轉。
消除關係:抽象出模組C,A依賴C(A使用C),B依賴C(B實現C),達到A和B不依賴關係。
兩個模組有循環相依性關係,通常就是一個模組,應該合并。如果不合并就要打破這種關係,解決辦法有:
上移:將依賴成因上移到高等級模組,建立一個更高等級模組,抽象出最低等級模組依賴關係,達到單向依賴。
下移:將依賴成因下移到高等級模組,與上移相反,建立一個更低等級模組而已。
回調:定義一個抽象體,將其注入到模組中,達到單向依賴甚至消除依賴個可能。其實通過反轉和消除,也能解決循環相依性,根據具體使用情境選擇吧。
7、模組應該輕量級,不依賴容器和運行環境,可單獨部署使用最好。
8、模組管理,如果不打算重用某個模組,那麼依賴管理的動力就是可維護性,如果想要可維護性提高,就要關注可測試性(越容易測試、則越容易維護)。最好在開始的時候儘可能簡單並隨著需求出現增強模組,而不是開始的時候基於預測建立複雜模組。
9、預設實現,模組應該有一個預設實現,如果沒有任何實現,模組實際上只是一個規範。(比如預設實現就是外掛程式式開發的一種方式。)
10、依賴抽象就必須保證擷取實作類別的執行個體時,不能new,常用方法有3類,Factory 方法、動態建立(如Spring注入)、OSGi μService。
11、如果依賴抽象體的所有類都在一個模組中,那麼將這些類和抽象體放在同一個模組中。如果依賴抽象體的所有類位於多個模組中,那麼將抽象體放到一個單獨的模組中。
最後說說為什麼要用OGSi來強制模組化,“優雅的理念設計在實現的過程中很快就可能變得一團糟,沒有開發人員能夠理解最初的進階願景要如何展現在代碼中。儘管你很清楚預期的模組關係是什麼,但是不想要的依賴依然會進入你的應用。”真實情況確實如此,不論什麼原因,最終的結果都是一樣的,就是我們的代碼越來越差,模組關係混亂了,代碼可以定期重構,但是模組重構的代價比較大,OGSi有個辦法強制解決,“等級化構建會強制你思考模組依賴...因為任何新的依賴都需要修改構建指令碼,所以對於開發人員,定義新的依賴必須要謹慎。等級化構建使引入新的依賴要做更多的事情。”
剛參加工作時,開發過程中很多功能如果使用前必須配置好幾處的設定檔,當時覺得非常麻煩,一直沒找到很令人信服的理由,讀完本書總算髮現了:
1、配置複雜通常代表著靈活程度高,越靈活使用起來越麻煩,越靈活越複雜,很多事都這樣,沒有完美,只有當前最適合的平衡點。
2、複雜的配置,讓開發人員更謹慎,如果沒有這麼複雜的配置,開發人員會隨便亂寫,最終造成系統極其糟亂。
3、複雜的配置,集中於一處或一類地方,也方便審查梳理。
最後,本書的模組化設計思想讓我收穫頗多,目前還不是特別流行,希望未來會變的非常流行,未來的OSGi也將會帶來生態系統(Eclipse就是成功基於OSGi的生態系統)。
(讀書筆記)Java應用架構設計-模組化模式與OSGi