解耦設計手法總結
設計是一個平衡的產物,需要在各個約束條件下(組織目標,業務目標,開發流程,技術能力,學習及維護成本等)不斷地進行演進。 我們雖然不提倡做大而全的設計,但會堅持進行基礎性設計,以保證我們的設計一直在正確的方向上演進。
設計演進的過程既可以是自上而下的,也可以是自下而上的。
基本設計原則
業界普遍被接受的設計原則不再贅述。這裡特別針對基於開源專案的軟體,其總體主旋律將是:跟隨,擴充套件,貢獻,其中跟隨將是一個基本能力,反觀深度定製的方式會遭遇越來越多的尷尬。落實在設計上,其最核心的設計原則:隔離自有業務。相較於模組化的低耦合、高內聚的原則,這裡的要求會更高。
先從模組上考慮應用的層次,依次考慮:
- 應用層
- 開源專案本身的定製或移植機制
- 新增的介面層
- 新增的適配層或業務層
- 既有的介面層
- 既有的實現
設計本身還要保證業務的完整性,以及對效能、系統開銷、卡頓和穩定性的要求。
解耦的設計實踐
以下為關於解耦的設計方法總結,以及應用要點便於在設計時評估。
解耦是隔離變化和降低複雜度的重要手段,這裡以解耦代言隔離變化,其思想就是以分工協作代替全面控制,介面的定義大於業務邏輯的定義。
其思考路徑是:分不分?如何分?
如何分是具體形式的問題,下面詳述。分不分則取決於功能需求, 常見分離的需求有:
-
功能強內聚
. 這沒什麼好說的, 最常見的理由。 -
功能的整合和轉換
. 就是為了整合某些功能或者達到某種切換的目的,向上提供一個更為標準統計的介面。內部可能會進行一些業務邏輯處理,資料、狀態轉換之類的操作。如編譯器分出前後端也是這樣的概念。 - 降低複雜度
介面的定義至關重要,介面本身不能繫結業務約束或者流程。整體互動上是面向無狀態的介面,而不是程式導向。過程的合理性,即業務流程則由不同的單元內部保障,再通過介面互動。
而向約束的程式設計也是在函式內進行約束的判斷,間接達到帶狀態介面。
在手法上可以概括為從巨集觀到微觀的四個層次:
-
程式
. 也可以是物理空間上的分離 - 庫
- 模組化/分層
-
程式碼
如下圖:
程式
以分程式的方法來進行協作是Unix世界的傳統,即KISS原則。Unix下有各式小工具,這些工具之間通過管道連結起來達到強大的功能。
另外以服務的方式隔離業務也很常見。如Windows中COM+的架構,甚至是HTTP Server等。
分程式的特點在於不同程式間的功能高度獨立,並行處理的情況較多,服務提供者能夠按需佈署,存在一對多的情況,或有額外的安全性考慮。
而挑戰在於效能、系統開銷,需要熟悉IPC以及共享記憶體的知識。
分庫
這是一個重要的模組化手法,主要是以動態庫和指令碼的形式, 甚至是獨立的程式提供擴充套件。其核心思想是以外掛的形式完成功能組裝,以物理分離的形式提供出來。
外掛本身實現一套標準的介面,包括:引數配置,接收輸入,狀態輸出,資料輸出等。
如Windows的核心驅動模組,Photoshop/GIMP中的影象處理功能,Matlab以及R語言中的函式庫等等,不勝列舉。
以靜態庫形式提供出來的模組,更接近於程式碼級或者分層級別的體現,無法直接達到按需佈署的能力。
分庫要求各個獨立庫的介面層比較單一,特別適用於業務邏輯強內聚的場景。同時外掛的功能將直接影響主程式的穩定性。
分層
就是將某一類功能的類和程式碼集中起來,向外提供特定介面或若干介面類,這個邏輯上的集合,就是層(layer)或者模組(module),也有叫unit或者API之類的。與分庫、分程式本質區別就在於它是一個邏輯集合,優勢在於可以更靈活的與不同模組互動,因為介面可以多樣化(支援程式碼級的互動),這也同樣是它的劣勢,有時導致它形同虛設,喪失瞭解耦的能力。
所以分層成功與否,關鍵在於介面(含介面類)的定義和控制。
常見的一些手法,如MVC, 膠合層(glue),適配層(port),WebKit和Chrome中也有應用。
程式碼
這是一個最為微觀,最為複雜的層次。但是到了這層,並不表示必然存在耦合問題。如果一些架構在設定上考慮到了擴充套件和適配的需求,在這個級別進行解耦反而最為自然。
WebKit的port方案
以Image類為例,它的一個函式與平臺相關,於是類的實現被放在了三個檔案中Image.cpp, ImageMac.mm和ImageWin.cpp中。Image.cpp中實現了公共的部分,而ImageMac.mm中實現了Mac OS版本,而ImageWin.cpp則實現了Windows版本。
另一種實現方式,如多媒體元素的播放控制元件。首先是MediaPlayer提供了一部分公共的邏輯,對於與平臺相關實現的部分,定義了一個MediaPlayerPrivateInterface,各平臺繼承自這個介面實現各自的邏輯。
當我們解決了架構上的解耦後,在模組內部引入一定的耦合度就不是問題了。可供選擇的方法就太多了。
Helper Class
Helper Class已經為一個類新增一個友類,執行一些差異化的業務。
Helper Class可以使用類似WebKit Port的機制為不同的系統提供不同的實現,也可以配合工廠模式,實現更為彈性的選擇。
分散的邏輯判斷就可以轉為函式呼叫。
關於helper的使用一直是有爭議,網上也有很多避免使用helper class的討論。 主要論調在於認為helper class是過程化的產物,思考時是考慮的是流程上的邏輯補充。
參考: 優化解耦的設計思考
自然而然的設計
WebKit模組化分析
Unix設計哲學
相關文章
- 微服務解耦設計模式 - Neeraj微服務解耦設計模式
- 詳解command設計模式,解耦操作和回滾設計模式解耦
- 複雜任務中,流程的解耦設計解耦
- Mybatis 原始碼解讀-設計模式總結MyBatis原始碼設計模式
- 常用設計模式總結,附完整圖解設計模式圖解
- 解耦解耦
- 【圖解設計模式系列】23句話總結23種設計模式圖解設計模式
- PHP設計模式總結PHP設計模式
- JavaScript設計模式總結JavaScript設計模式
- 前端設計模式總結前端設計模式
- 設計原則總結
- AppDelegate解耦APP解耦
- 設計模式總結 —— 單例設計模式設計模式單例
- 資料庫設計總結資料庫
- 程式設計感悟總結一程式設計
- 設計模式總結(模式篇)設計模式
- Nio程式設計模型總結程式設計模型
- C++設計模式 - 總結C++設計模式
- 【程式設計素質】程式設計思想總結程式設計
- 計算機程式設計心得總結計算機程式設計
- iOS架構設計解耦的嘗試之VC邏輯AOP切割iOS架構解耦
- 遊戲中的“女神”角色都有哪些設計手法?遊戲
- JS非同步程式設計之Promise詳解和使用總結JS非同步程式設計Promise
- MySQL 資料庫設計總結MySql資料庫
- PROG2007程式設計總結程式設計
- Java設計模式簡介(總結)Java設計模式
- restful介面設計規範總結REST
- Javascript非同步程式設計總結JavaScript非同步程式設計
- 設計模式總結(理論篇)設計模式
- MR核心程式設計思想總結程式設計
- 設計用例的方法總結
- 一文總結設計模式設計模式
- 網頁設計的技巧總結網頁
- 建立型設計模式對比總結 設計模式(八)設計模式
- 巧用Fragment解耦onActivityResultFragment解耦
- 遊戲基礎知識——“速成力量”的設計手法遊戲
- 遊戲基礎知識——“斥候”角色的設計手法遊戲
- 乾貨:遊戲中“沙漠”場景的設計手法遊戲
- 遊戲基礎知識——“英雄之死”的設計手法遊戲