模塊
模塊就是從邏輯上將系統分解為更細微的部分, 分而治之, 復雜問題拆解為若干簡單問題, 逐個解決.
耦合主要描述模塊之間的關系, 內聚主要描述模塊內部. 模塊的粒度可大可小, 可以是函數, 類, 功能塊等等.
耦合
模塊之間存在依賴, 導致改動可能會互相影響, 關系越緊密, 耦合越強, 模塊獨立性越差.
比如模塊A直接操作了模塊B中數據, 則視為強耦合, 若A只是通過數據與模塊B交互, 則視為弱耦合.
獨立的模塊便於擴展, 維護, 寫單元測試, 如果模塊之間重重依賴, 會極大降低開發效率.
內聚
模塊內部的元素, 關聯性越強, 則內聚越高, 模塊單一性更強. 一個模塊應當盡可能獨立完成某個功能,
如果有各種場景需要被引入到當前模塊, 代碼質量將變得非常脆弱, 這種情況建議拆分為多個模塊.
低內聚的模塊代碼, 不管是維護, 擴展還是重構都相當麻煩, 難以下手.
接口設計原則
好的接口應當滿足設計模式六大原則, 很多設計模式, 框架都是基於高內聚低耦合這個出發點的.
- 單一職責原則: 一個類只負責一個功能領域中的相應職責.
- 開閉原則: 一個軟件實體應當對擴展開放,對修改關閉.
- 里氏代換原則: 所有引用基類(父類)的地方必須能透明地使用其子類的對象.
- 依賴倒轉原則: 抽象不應該依賴於細節, 細節應當依賴於抽象. 換言之, 要針對接口編程, 而不是針對實現編程.
- 接口隔離原則: 使用多個專門的接口, 而不使用單一的總接口, 即客戶端不應該依賴那些它不需要的接口.
- 迪米特法則: 一個軟件實體應當盡可能少地與其他實體發生相互作用, 例如外觀模式, 對外暴露統一接口.
舉幾個栗子
外觀模式
為系統中多個子系統提供一致的對外調用, 對客戶端隱藏子系統細節, 降低其與子系統的耦合.
橋接模式
JDBC中的把面向廠商的接口(Driver)和面向使用者的API(DriverManager)做了拆分隔離.
1 // 開發者只需要關注JDBC API, 無需關注不同數據庫Driver接口實現 2 Class.forName("com.mysql.jdbc.Driver"); 3 Connection conn = DriverManager.getConnection(url, username, password);
適配器模式
引入第三方庫(hibernate, log4j), 不應該直接在代碼中繼承或者使用其實體類.
需要抽出上層統一接口, 然后增加實現類, 對外暴露接口.
1 // 代碼與log4j強耦合, 不推薦 2 org.apache.log4j.Logger.getRootLogger().info("info"); 3 // 底層可以隨意更換log框架 4 FRLoggerFactory.getLogger().info("info");