內聚和耦合有什麼區別? 編程
耦合和內聚如何致使軟件設計的好壞? 編程語言
有哪些例子能夠概述二者之間的差別,以及它們對總體代碼質量的影響? 函數
軟件工程中的凝聚力是某個模塊的元素屬於一塊兒的程度。 所以,它是衡量軟件模塊的源代碼所表示的每一個功能的強烈關係的度量。 spa
用通俗的話說耦合 ,是多少錢一個組件(再次,想象一類,雖然不必定)知道的內部運做或另一個內部元素,也就是說,它多少知識有其餘成分的。 設計
若是您想經過示例和圖紙閱讀更多細節, 我寫了一篇關於此的博客文章 。 我認爲它回答了你的大部分問題。 code
凝聚力的最佳解釋來自鮑勃叔叔的清潔代碼: orm
類應該有少許的實例變量。 類的每一個方法都應該操縱這些變量中的一個或多個。 一般,方法操做的變量越多,該方法對其類的內聚性就越強 。 每種方法使用每一個變量的類最大程度地具備內聚性。 對象
通常來講,建立這樣的最大內聚類是不可取的也不可能的; 另外一方面, 咱們但願凝聚力很高 。 當內聚力很高時,這意味着類的方法和變量是相互依賴的,而且做爲一個邏輯總體掛在一塊兒。 接口
保持函數較小並使參數列表保持較短的策略有時會致使方法子集使用的實例變量的增長。 當發生這種狀況時,它幾乎老是意味着至少有一個其餘類試圖離開更大的類。 您應該嘗試將變量和方法分紅兩個或更多個類,以便新類更具凝聚力。 rem
模塊內的高內聚性和模塊之間的低耦合一般被認爲與OO編程語言中的高質量相關。
例如,每一個Java類中的代碼必須具備高內部內聚力,但儘量鬆散地耦合到其餘Java類中的代碼。
Meyer的面向對象軟件構建(第2版)的第3章是對這些問題的一個很好的描述。
內聚是指類(或模塊)能夠作什麼。 低凝聚力意味着班級作了各類各樣的行動 - 它是普遍的,沒有關注它應該作什麼。 高凝聚力意味着課程專一於應該作的事情,即只關注課堂意圖的方法。
低內聚的例子:
------------------- | Staff | ------------------- | checkEmail() | | sendEmail() | | emailValidate() | | PrintLetter() | -------------------
高內聚的例子:
---------------------------- | Staff | ---------------------------- | -salary | | -emailAddr | ---------------------------- | setSalary(newSalary) | | getSalary() | | setEmailAddr(newEmail) | | getEmailAddr() | ----------------------------
至於耦合 ,它指的是兩個類/模塊相互依賴或相互依賴的方式。 對於低耦合類,更改一個類中的主要內容不該該影響另外一個類。 高耦合會使您難以更改和維護代碼; 因爲課程緊密相連,所以進行更改可能須要對整個系統進行改造。
良好的軟件設計具備高內聚力和低耦合性 。
增長的內聚力和減小的耦合確實致使良好的軟件設計。
Cohesion對您的功能進行分區,使其簡潔且最接近與其相關的數據,同時解耦確保功能實現與系統的其他部分隔離。
解耦容許您更改實現,而不會影響軟件的其餘部分。
Cohesion確保實現更具體功能,同時更易於維護。
下降耦合和增長內聚力的最有效方法是經過界面設計 。
這是主要功能對象應該只經過它們實現的接口「相互」「知道」。 界面的實現引入了凝聚力做爲天然結果。
雖然在某些狀況下不現實,但應該是一個設計目標。
示例(很是粗略):
public interface IStackoverFlowQuestion void SetAnswered(IUserProfile user); void VoteUp(IUserProfile user); void VoteDown(IUserProfile user); } public class NormalQuestion implements IStackoverflowQuestion { protected Integer vote_ = new Integer(0); protected IUserProfile user_ = null; protected IUserProfile answered_ = null; public void VoteUp(IUserProfile user) { vote_++; // code to ... add to user profile } public void VoteDown(IUserProfile user) { decrement and update profile } public SetAnswered(IUserProfile answer) { answered_ = answer // update u } } public class CommunityWikiQuestion implements IStackoverflowQuestion { public void VoteUp(IUserProfile user) { // do not update profile } public void VoteDown(IUserProfile user) { // do not update profile } public void SetAnswered(IUserProfile user) { // do not update profile } }
在代碼庫中的其餘地方,您能夠擁有一個處理問題的模塊,不管它們是什麼:
public class OtherModuleProcessor { public void Process(List<IStackoverflowQuestion> questions) { ... process each question. } }