上次關于如何編寫代碼的文章里面提到了應用的模塊化和分層,這篇文章就來聊聊這個事情。
沒有頂層設計、模塊劃分的應用就像一團打結的毛線,代碼分支可能會跳來跳來,沒有邊界。很難理清楚內部的業務邏輯,更糟糕的是隨著需求的堆積,日積月累更難理清楚內部的模塊劃分,所以從一開始就應該定好系統的模塊,確定好邊界之后才知道每一部分往哪里放。
每次實現一個新需求內心都有一個層次樹,大概會在哪個模塊加什么東西,傳統的MVC 模型在web 應用流行了很久,也很容易理解,下面我基于之前實現的一個系統做了些修剪和設計,形成了一個比較通用的分層架構。
如下圖:后面分別講解每一個模塊的職責。
應用分層和模塊化
controller
控制器層大家應該都不陌生,寫過web應用的都知道,這個是http 請求的入口,controller 負責接受web請求HttpRequest, 返回HttpResponse。
biz-service-api
業務服務層的接口定義,一般簡單的應用不需要區分 biz-service 和 core-service,但是如果業務復雜度比較高,最佳實踐是把service 拆二層,biz-service 負責業務邏輯,業務邏輯是繁雜多樣的,隨時會變,而那些具有通用性的基礎能力、有時候也叫平臺能力放到core-service 里面,比如很多業務都需要支付能力,支付的服務就可以作為平臺能力放在core-service 提供給biz-service使用。biz-service 使用core-service的能力,在阿里內部系統,非常重視core-service,如果系統拆分成域來看,core-service 可以理解成中臺,biz-service 是前臺,大中臺小前臺戰略除了在組織結構上,也可以在應用內體現,一般都是把中臺能力做強,前臺能力負責靈活、高效滿足業務需求。
facade
門面接口,和設計模式里面的門面有點像,facade 模塊只定義接口,具體實現放在biz-service-impl 模塊。facade 一般是提供給外部系統的,打成jar 包,人家依賴你,只需要知道接口定義的出入參,具體實現他不需要關心。你的facade 服務發布成rpc provider,為上游提供服務。
其實有很多系統會把facade 層放在core-service 層下面,因為認為facade 提供的服務都是rpc 服務,一般只在內部發布,但是我覺得放在和controller 一層邏輯比較順,也比較清晰,當然也是因為調用我controller 的也是內部系統,所以我一視同仁。
biz-service-impl
業務邏輯實現,實現facade 接口和 biz-service-api。
core-service-api
核心能力服務api定義。核心原子能力的定義,比如支付能力、模型運行能力、通用對象定位能力、安全。
core-domain
這里承載核心領域,最重要的模型都放在這個模塊,有的架構設計這里除了模型,還會防model-service,但是我還是覺得模型更多是數據的概念,模型的操作應該是自包含的,也就是模型的操作只依賴自己的數據,可以直接在模型內部完成,如果需要多個模型參與的操作都應該交給core-service 來完成。算是DDD 領域驅動設計的折中,可理解性比規范有時候更重要,這方面的例子還很多,比如大型互聯網公司的表設計就沒有遵循數據庫規范的范式,表join 都很少,單表冗余情況很多。
infrastructure
基礎的比如數據庫、緩存、消息隊列、流程引擎、審批流、定時任務這種系統基礎設施,還有第三方外部系統依賴都放在這一層。一般我的建議是每引入一個第三方服務或者組件,都定義service-api 和 serviceImpl,api做出通用性的,不依賴具體第三方的存在,這樣比如接入了A 公司提供的流程引擎,發現不合適,不好用的時候api 這一層不用動,也不會影響到上層應用的服務,而且還可以非常好的支持SPI機制,方便切流到新服務提供者上去。
上面有的是按照層的概念說的,有的是按照模塊來說的。這篇文章我自己覺得挺有價值的,工程上的一些最佳實踐,希望對大家在做應用架構設計的時候有幫助。
原文鏈接:https://mp.weixin.qq.com/s/-Ae2GnPwWFnpKFtQTKOCKA