内聚和耦合有什么区别? 编程
耦合和内聚如何致使软件设计的好坏? 编程语言
有哪些例子能够概述二者之间的差别,以及它们对总体代码质量的影响? 函数
软件工程中的凝聚力是某个模块的元素属于一块儿的程度。 所以,它是衡量软件模块的源代码所表示的每一个功能的强烈关系的度量。 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. } }