本文為讀書筆記,對書中內容進行重點概括,並將書中的模組化結合微服務、Java9 Jigsaw談談理解。
本書概括
以Java軟體系統為例,重點講解了應用架構中的物理設計問題,即如何將軟體系統拆分為模組化系統。所以內容組織包括為什麼需要模組化,圍繞如何實現模組化講述了模組化模式,最後在模組化基礎上使用OSGi技術實現動態模組化。
內容總結
模組化定義
先談談應用架構的邏輯設計和物理設計。
邏輯設計是關於語言結構的,指類、方法之間的關係,組織結構。物理設計是關於軟體中的物理實體,即部署單元和他們之間的關係,是關於如何將系統拆分為模組系統的。
模組定義:
軟體模組是獨立可部署的、可管理的、程式內可重用的、無狀態的軟體單元。可管理即模組可以安裝、解除安裝和更新。
在Java中,模組就是jar包。
與分散式服務不同的是,這裡的模組是程式內重用,需要與想用其功能的程式一起部署,而服務是一次部署被多個client使用。
模組化的理由
- 僅關注高層抽象是不夠的,只強調程式碼質量也是不夠的,模組化能填補高層架構與底層程式碼之間的空白,增加設計的靈活性,幫助實現高適應性、高可維護性的系統架構。
- 模組是內聚的,變化將侷限在模組的實現細節中,即能封裝變化,所以能減小複雜性,降低維護成本。
- 模組化提供了指導和規律,讓我們可以在最小化依賴的同時又能最大化重用的潛能,幫助我們平衡模組的重量級和粒度。這裡粒度指一個系統要拆分的各個部分的範圍大小,重量級指模組對其他環境依賴的程度。最大化重用會使得可用複雜化,設計軟體時,圍繞模組的重量級和粒度的權衡是很重要的因素,對系統的模組化都是與專案上下文相關並且要符合當時的情況。一些特定級別的重用已經很成熟了,如ORM框架,Netty框架等。
- 跨應用重用是服務的最佳用武之地,但通常是粗粒度的,即所做的事情超出我們的需要,如果需要跨應用重用一些需要的行為呢?沒有模組的情況下,我們的選擇是將其暴露為服務或者複製類的程式碼,兩者都不理想,模組化就是另一種選擇,在粒度上,模組是比服務更小的單元且是部署單元。
模組化模式
-
基本模式
- 管理關係:設計模組之間的關係
- 模組重用:強調模組級別的重用
- 模組內聚:模組的行為應該只服務於一個目的
-
依賴模式
- 非迴圈關係:模組之間的關係非迴圈依賴
- 等級化模組:模組關係是等級化的,物理分層旨在為組成應用的分層建立多個模組,更多是與職責相關,而等級與理解系統的結構和關係更為密切,比分層更為細粒度,一個分層可能會有多個等級。
- 物理分層:模組關係不影響物理分層,如展現、領域、DAO。
- 容器獨立:模組不依賴於具體容器,採用輕量級容器,如Spring
- 獨立部署:模組可獨立部署
-
可用性模式
- 釋出介面:暴露API
- 外部配置:使用獨立的配置檔案用於不同的上下文。外部化配置增加了模組的重用行,但降低的易用性。如一個提供連線池的模組,user,password通過配置檔案配置而不是硬編碼在模組中,這就方便重用,但會使得易用性降低,因為使用之前必須配置對應的上下文
- 預設實現:為模組介面提供預設實現,並提供擴充套件機制,預設實現有助於在重用和易用之間取得平衡。如dubbo的擴充套件點機制
- 模組門面:為底層細粒度模組建立一個門面,提供高層API協調一組細粒度模組的行為
-
擴充套件性模式
- 抽象化模組:依賴於抽象而不是具體,典型的例子如通過Spring注入具體實現,bean裡面依賴的屬性是介面
- 實現工廠:通過實現工廠建立適當的物件引用,如Spring的裝配
- 分離抽象:將抽象類與實現類放在各自的模組中,從而能用新的實現替換已有的實現,幫助建立靈活和可擴充套件的系統
-
通用模式
- 就近異常:異常定義應該接近丟擲他們的模組
- 等級化構建:按照模組的等級構建
- 測試模組:每個模組應該有一個對應的測試模組
模組化與OSGi
OSGi是Java平臺中的動態模組系統,定義了一個模組化單元,稱之為bundle,是一個jar檔案。bundle會在同一個JVM中進行部署和互動,在程式內跨bundle互動,並且可動態部署bundle。
OSGi只是提供一個執行時環境,使得在Java平臺中實現模組化成為可能。
書中好詞好句
自上而下的架構
架構的目標是減少變化的成本和影響
軟體傾向於隨著時間變得腐化,隨著時間流逝,變化會悄然發生並以難以預料的方式考驗著設計
技術債用來描述為了滿足進度或使用者期望而做出的設計讓步,與財務債一樣,也需要支付利息,在將來的開發中要付出額外的努力。我們可以選擇繼續支付利息或用更好的設計重構來償還本金,儘管償還本金需要成本,但是會降低將來要支付的利息。
複雜性阻止我們以優雅的方式使軟體系統適應需求的變化。
最大化重用會使得可用複雜化。即軟體模組的可重用性越高,則其易用性越差。
模組化與微服務
通過上文的描述,我們已經瞭解了模組化思想,那與如今的微服務是什麼關係呢?
微服務也是可獨立部署於容器的,每個微服務僅關注於完成一件任務並很好地完成該任務,每個任務代表著一個小的業務能力。各個微服務之間通過輕量級協議(RESTful API介面, 輕量級訊息機制)互動通訊。與模組化強調的程式內重用不同,微服務屬於分散式服務,通過RPC協議在程式間重用。
相似點:
兩者都是可獨立部署的,重視邏輯的可複用性,強調一個大的軟體系統需要拆分為各個部分,保持高內聚低耦合,實現更好的軟體架構。
個人理解:
微服務架構更勝一籌於模組化架構思想。提出模組化架構的本書(中文版)發版於2013年,微服務的概念源於2014年,兩者目的相似,現如今已有大量企業對已有系統進行改造或實施微服務架構,開發人員對微服務的認知逐漸深入,大的市場環境已經採用了微服務架構。又微服務已經是一個較小且完整的業務部署單元,不會將其拆分為多個模組化單元在同一程式中部署,就算拆分也是將其拆分為更細粒度的微服務。
雖然實施微服務需要具備完善的基礎設施,如容器化、服務註冊發現、配置管理、監控等DevOps開發運維一體化設施,但隨著應用雲化的日益普及,相關設施不斷完善,如SpringCloud,其實施的門檻已經較低了。
且動態模組化技術如OSGi尚未普及,所以,個人認為微服務架構比模組化架構更優。
模組化與Java9 Jigsaw
Java 9Java 平臺模組化專案(Jigsaw )參考 https://mp.weixin.qq.com/s/Sr...
參考
微服務相關:
https://www.ibm.com/developer...
https://martinfowler.com/micr...