## 連載:面向對象葵花寶典:思想、技巧與實踐(28) - 設計原則:內聚&耦合
前面通過實例講解了一個一環扣一環的面向對象的開發流程:用例模型 -> 領域模型 -> 設計模型(類模型 + 動態模型),解答了面向對象如何做的問題。接下來我們就要講“如何做好面向對象設計”的技巧了
===================================================================
**【內聚】**
參考維基百科的解釋,內聚的含義如下:
cohesion?refers?to?the?degree?to?which?the?elements?of?a?[module](http://en.wikipedia.org/wiki/Module_(programming))?belong?together.
(http://en.wikipedia.org/wiki/Cohesion_(computer_science))
翻譯一下即:**內聚指一個模塊內部元素彼此結合的緊密程度**。
看起來很好理解,但深入思考一下,其實沒有那么簡單。
首先:“模塊”如何理解?
你一定會說,“模塊”當然就是我們所說的系統里的“XX模塊”了,例如一個ERP系統的“權限”模塊,一個電子商務的“支付”模塊,一個論壇網站的“用戶管理”模塊。。。。。。等等
?
你說的沒錯,但在面向對象領域,談到“內聚”的時候,模塊的概念遠遠不止我們通常所理解的“系統內的某個模塊”這個范圍,而是可大可小,大到一個子系統,小到一個函數,你都可以理解為內聚里所說的“模塊”。
?
所以,你可以用“內聚”來判斷一個函數設計是否合理,一個類設計是否合理,一個接口設計是否合理,一個包設計是否合理,一個模塊/子系統設計是否合理。
?
其次:“元素”究竟是什么?
有了前面對“模塊”的深入研究后,元素的含義就比較容易明確了(不同語言稍有不同)。
函數:函數的元素就是“代碼”
類/接口:類的元素是“函數、屬性”
包:包的元素是“類、接口、全局數據”等
模塊:模塊的元素是“包、命名空間”等
?
再次:“結合”是什么?
英文的原文是“belong”,有“屬于”的意思,翻譯成中文“結合”,更加貼近中文的理解。但“結合”本身這個詞容易引起誤解。絕大部分人看到“結合”這個單詞,想到的肯定是“你中有我、我中有你”這樣的含義,甚至可能會聯想到“美女和帥哥”的結合,抑或“青蛙王子和公主”的結合這種情況。
這樣的理解本身也并沒有錯,但比較狹隘。
我們以類的設計為例:假如一個類里面的函數都是只依賴本類其它函數(當然不能循環調用啦),那內聚性肯定是最好的,因為“結合”得很緊密。
?
但如果這個類的函數并不依賴本類的函數呢?我們就一定能說這個類的內聚性不好么?
其實也不盡然,最常見的就是CRUD操作類,這幾個函數相互之間沒有任何結合關系(某些設計可能會先查詢再修改,但這樣的設計不是事務安全的),但其實這幾個函數的內聚性非常高。
?
所以,關于內聚的結合概念,我認為不是非常恰當的描述。那么,就究竟什么才是真正的“內聚”呢?
答案就藏在顯而易見的地方,翻開你的詞典,仔細看看cohesion的含義,你會看到另外一個解釋:凝聚力!
?
**“凝聚力”就是“內聚”的核心思想**,拋開面向對象不談,我們日常工作中幾乎隨處可見“凝聚力”:
你可能會說,你的團隊很有凝聚力。。。。。。
領導可能會說:我們要增強團隊的凝聚力。。。。。。
成功學大師會說:凝聚力是一個團隊成功的基石。。。。。。。
?
面向對象領域的“凝聚力”,和團隊的“凝聚力”是一樣的概念。
l?判斷團隊凝聚力時,我們關注團隊成員是否都專注于團隊的目標;判斷面向對象模塊的凝聚力時,我們同樣關注元素是否專注于模塊的目標,即:模塊本身的職責!
l?判斷團隊凝聚力時,我們還會關注團隊成員之間是否互相吸引和幫助;判斷面向對象模塊凝聚力時,我們同樣關注元素間的結合關系;
?
雖然判斷內聚性的時候我們會考慮元素的結合情況,**但其實是否專注模塊的職責,才是內聚性的充要條件**。
當模塊的元素全部都專注于模塊的職責的時候,即使元素間的結合不是很緊密,也是符合內聚性的要求的,這也是CRUD設計符合內聚性的原因。
?
所以,判斷一個模塊(函數、類、包、子系統)“內聚性”的高低,最重要的是關注模塊的元素是否都忠于模塊的職責,簡單來說就是“不要掛羊頭賣狗肉”。
**【耦合】**
參考維基百科,耦合的定義如下:
?coupling?or?dependency?is?the?degree?to?which?each?[program?module](http://en.wikipedia.org/wiki/Module_(programming))?relies?on?each?one?of?the?other?modules
(http://en.wikipedia.org/wiki/Coupling_(computer_science))
簡單翻譯一下:耦合(或者稱依賴)是程序模塊相互之間的依賴程度。
?
從定義來看,耦合和內聚是相反的:內聚關注模塊內部的元素結合程度,耦合關注模塊之間的依賴程度。
?
理解耦合的關鍵有兩點:什么是模塊,什么是依賴。
?
什么是模塊?
模塊和內聚里面提到的模塊一樣,耦合中的模塊其實也是可大可小。常見的模塊有:函數、類、包、子模塊、子系統等
?
**什么是依賴?**
依賴這個詞很好理解,通俗的講就是某個模塊用到了另外一個模塊的一些元素。
例如:A類使用了B類作為參數,A類的函數中使用了B類來完成某些功能。。。。。。等等
- 前言
- (1) - 程序設計思想的發展
- (2) - 面向對象語言發展歷史
- (3) - 面向過程 vs 面向對象
- (4) - 面向對象是瑞士軍刀還是一把錘子?
- (5) - 面向對象迷思:面向對象導致性能下降?
- (6) - 不要說你懂“類”
- (7) - “對象”新解
- (8) - “接口” 詳解
- (9) - “抽象類” 詳解
- (10) - “抽象” 詳解
- (11) - “封裝” 詳解
- (12) - “繼承” 詳解
- (13) - “多態” 詳解
- (14) - 面向對象開發技術流程
- (15) - 需求詳解
- (16) - 需求分析終極目的
- (17) - 需求分析518方法
- (18) - 用例分析
- (19) - 功能點提取
- (20) - 用例圖的陷阱
- (21) - SSD
- (22) - 領域模型
- (23) - 領域建模三字經
- (24) - 設計模型
- (25) - 類模型
- (26) - 類模型三板斧
- (27) - 動態模型設計
- (28) - 設計原則:內聚&耦合
- (29) - 高內聚低耦合
- (30) - SRP原則
- (31) - OCP原則
- (32) - LSP原則
- (33) - ISP原則
- (34) - DIP原則
- (35) - NOP原則
- (36) - 設計原則如何用?
- (37) - 設計模式:瑞士軍刀 or 錘子?
- (38) - 設計模式之道
- (39) - 設計原則 vs 設計模式
- (40) - DECORATOR模式
- (完)- 書籍已經出版