為什么寫這個主題?
軟件設計中間加一層的解決方案,隨處可見。寫本文的目的也是因為看到很多場景都是基於這個思想的應用,就想着梳理一下,讓大家看到一些本質的內容。
順便以現今主流的一些技術或概念作為樣本,進行拆解,輔助大家理解。
搞清底層邏輯和設計思想,才不會被各種技術名詞,技術概念整的一臉懵逼。
現在鋪天蓋地的三高講解、培訓,千萬悠着點學,別整的身體三高了,哈哈,開個玩笑。
但是軟件的設計思想層面的東西,編程的一些思考,我們也需學習提升,思考沉淀。學技術不只有三高。
而且思維層面的東西不像學習個具體的技術框架,全身心投入個幾天甚至幾個小時就能上手使用了。而是需要一點一滴積累,一點一滴思考總結。
看別人的總結也不行,別人的永遠是別人的,參考可以,一定要自己總結。
正文開始
你熟悉的jvm
先看個jvm得簡易執行圖。

通過在class與操作系統之間加上JVM之后,以后出現新的操作系統,只需要針對對應平台實現一套JVM(JVM的各平台實現是不需要我們關心的,有官方團隊處理),項目即可在平台上運行,這便是Java宣稱的一次編寫,到處運行。到處運行的前提是,到處都需要有JVM的實現。
JVM在這里就充當了一個中間層,隔離了開發環境與操作系統。
隔離的好處是消除了雙方之間直接接觸帶來的相互影響和不適應,這些都在JVM這一層化於無形。
對項目開發人員來說就不用關心底層是什么操作系統,我只對接JVM。操作系統的任何變化、升級都跟我無關,這都是JVM需要考慮的事。
對操作系統而言,也不需要因為要運行你的class而做出任何改變。這也是JVM需要考慮的事。
那些不知道在哪能用上的設計模式
代理模式
算是設計模式中比較簡單也比較容易理解的一種,看個圖。

外觀模式
同樣先看個圖

中間加了外觀角色這個中間層后,對調用方來說,就變得簡單了許多,原來哼哧哼哧調3個,現在簡簡單單調一個。
其他還有不少,限於篇幅,就不列舉了。
消息中間件
這里主要說下用消息中間件解耦的場景,兩個服務之間消除依賴,借助消息中間件即可實現,不用消息中間件可以實現嗎,完全可以,自己實現一個中間的交換系統沒什么不可以,只不過需要投入時間精力,所以大家都用現成的。
此場景下僅僅解耦兩個服務之間的依賴其實是沒什么可炫耀的,它真正的威力在於加了中間層后將多服務之間多對多的調用結構轉換為了多對一結構。
如下圖

網關
還是先看個圖

加上網關這個中間層后,一方面可以隱藏真實服務的訪問地址,另一方面對調用方來說統一了調用入口,同時可以在網關層統一對所有后端服務添加全局的處理邏輯,如鑒權、限流、日志記錄等等。
最后再舉個項目中的場景
之前項目中遇到的一個場景是,需要通過一個很復雜的統計SQL最終輸出一個客戶想要的結果,數據量較大時查詢非常慢,在數據實時性要求不高,又不想引入多余技術組件的情況下,怎么處理這種問題 ?
解決辦法就是加個中間結果表,定時執行統計SQL將結果輸入到結果表,查詢功能直接查詢結果表,就很方便的解決了。處理過程如下圖

以上僅僅列舉了部分內容,沒提到的就只能留給讀者自行發覺領悟嘍。
總結
結合上面的實例拆解,總結下,中間加一層的設計來說大概可以解決以下場景的問題。
這里特別強調下加一層是個設計思想,不光可以解決技術問題,工作中日常生活中也可以用到,所以關鍵的關鍵是需要吸收這種設計思想。
再回到技術場景下來說不同場景的處理方式會不一樣,不一定是非要引入一個技術組件這樣,比如某些特定場景下,加個字段,加個類都可以實現。一定要活學活用。
解耦
解耦的目的是為了后續可擴展,可維護,提升軟件的可修改性,保證各自的獨立進化。
聚合
為了簡化上層調用和方便獲取結果,添加一個聚合中間層,這里還是帶一點解耦和隱藏細節的作用,雖說不是聚合的重點,但確有此功效。
統一處理
典型場景如上面提到的網關的應用場景和作用,如鑒權中心,日志記錄等都可以在網關層統一去做。
隱藏細節
系統有沒有自己的一些小秘密不想讓外界知道,有怎么辦 ?加上一個對外的調用層,隱藏真實服務地址,改變方法名,改變參數你想做的通通可以做到。
屏蔽差異
上面沒提到的對應的場景,其實拿設計模式中的適配器來說這個比較合適,一個典型的場景是一個兩插的插頭如何接入到一個三口的插座上。中間加個轉換頭就可以做到。通過轉接頭間接屏蔽了接口間的差異。
對應到系統中也是如此,一個接口輸出的是xml,而另一個接收方需要的是json,兩方都不能改動情況下,怎么做,那就是加個中間轉換層。屏蔽數據報文的差異。
最后
好的設計其實一定程度上可以避免一些技術問題,簡化問題場景,而這需要我們不斷摸索、不斷嘗試、不斷學習、不斷總結。
覺得還行,動動手指留個贊。
以上就是今天的內容,我們下期見。