内聚和耦合之间的区别是什么?
耦合和内聚如何导致软件设计的好坏?
举些什么例子来概括这两者之间的区别,以及它们对整体代码质量的影响?
内聚和耦合之间的区别是什么?
耦合和内聚如何导致软件设计的好坏?
举些什么例子来概括这两者之间的区别,以及它们对整体代码质量的影响?
当前回答
简单地说,内聚意味着一个类应该代表一个单一的概念。
如果类的所有特性都与类所代表的概念相关,那么类的公共接口就是内聚的。 例如,与其拥有CashRegister类,不如拥有CashRegister和Coin功能,将其整合为2个类- CashRegister和Coin类。
在耦合中,一个类依赖于另一个类,因为它使用类的对象。
高耦合的问题在于它会产生副作用。一个类中的一个更改可能导致另一个类中出现意外错误,并可能破坏整个代码。
通常,高内聚和低耦合被认为是高质量的OOP。
其他回答
简单地说,内聚性表示代码库的一部分在逻辑上形成单个原子单元的程度。另一方面,耦合表示单个单元对其他单元的依赖程度。换句话说,它是两个或多个单元之间的连接数。数量越少,耦合越低。
本质上,高内聚意味着将代码库中相互关联的部分保存在一个地方。同时,低耦合是关于尽可能多地分离代码库中不相关的部分。
从内聚和耦合角度来看的代码类型:
理想是遵循指导方针的代码。它是松散耦合和高度内聚的。我们可以用下图来说明这样的代码:
God Object是引入高内聚和高耦合的结果。它是一种反模式,基本上代表一段一次性完成所有工作的代码: 当不同类或模块之间的边界选择不当时,就会出现选择不当的情况
破坏性解耦是最有趣的一种。当程序员试图解耦代码库时,有时会发生这种情况,以至于代码完全失去了重点:
点击这里阅读更多
提高内聚性和降低耦合确实会带来好的软件设计。
内聚对功能进行了划分,使其简洁并与相关数据最接近,而解耦则确保功能实现与系统的其余部分隔离。
解耦允许您在不影响软件其他部分的情况下更改实现。
内聚性确保实现更特定于功能,同时更容易维护。
减小耦合、提高内聚的最有效方法是采用界面设计。
也就是说,主要的功能对象只能通过它们实现的接口相互“认识”。接口的实现自然会引入内聚性。
虽然在某些场景中不太现实,但这应该是一个设计目标。
例子(非常粗略):
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.
}
}
耦合=两个模块之间的交互/关系… 内聚=模块内两个元素之间的交互。
软件是由许多模块组成的。模块由元素组成。把一个模块看作一个程序。程序中的函数是一个元素。
在运行时,一个程序的输出被用作另一个程序的输入。这称为模块与模块之间的交互或流程与流程之间的通信。这也称为耦合。
在单个程序中,函数的输出被传递给另一个函数。这称为模块内元素的交互。这也被称为内聚。
例子:
耦合=两个不同家庭之间的交流…… 凝聚力=家庭中父亲、母亲和孩子之间的交流。
cohesion refers all about how a single class is designed. Cohesion is the Object Oriented principle most closely associated with making sure that a class is designed with a single, well-focused purpose. The more focused a class is, the cohesiveness of that class is more. The advantages of high cohesion is that such classes are much easier to maintain (and less frequently changed) than classes with low cohesion. Another benefit of high cohesion is that classes with a well-focused purpose tend to be more reusable than other classes.
在上图中,我们可以看到,在低内聚情况下,只有一个类负责执行大量不相同的作业,这降低了可重用性和维护的机会。但是在高内聚的情况下,所有的作业都有一个单独的类来执行特定的作业,这样可以获得更好的可用性和可维护性。
关于内聚的最好解释来自Bob叔叔的《Clean Code》:
类应该有少量的实例变量。类的每个方法都应该操作一个或多个这样的变量。一般来说,方法操作的变量越多,该方法与其类的内聚性就越强。每个方法使用每个变量的类具有最大的内聚性。
一般来说,创建这种最大限度内聚的类既不可取,也不可能;另一方面,我们希望内聚力高。当内聚性高时,这意味着类的方法和变量是相互依赖的,并作为一个逻辑整体挂在一起。
保持函数小和参数列表短的策略有时会导致由方法子集使用的实例变量激增。当这种情况发生时,几乎总是意味着至少有一个其他类试图从较大的类中退出。您应该尝试将变量和方法分离到两个或多个类中,以便新类更具内聚性。