内聚和耦合之间的区别是什么?

耦合和内聚如何导致软件设计的好坏?

举些什么例子来概括这两者之间的区别,以及它们对整体代码质量的影响?


当前回答

在面向对象编程语言中,模块内部的高内聚和模块之间的低耦合通常被认为与高质量有关。

例如,每个Java类中的代码必须具有较高的内部内聚性,但要尽可能地与其他Java类中的代码松散耦合。

Meyer的面向对象软件构建(第二版)的第3章对这些问题进行了很好的描述。

其他回答

我认为区别可以归结为以下几点:

内聚表示代码库的一部分在逻辑上形成单一原子单元的程度。 耦合表示单个单元独立于其他单元的程度。 在不破坏内聚的情况下存档完全解耦是不可能的,反之亦然。

在这篇博文中,我将对此进行更详细的描述。

关于内聚的最好解释来自Bob叔叔的《Clean Code》:

类应该有少量的实例变量。类的每个方法都应该操作一个或多个这样的变量。一般来说,方法操作的变量越多,该方法与其类的内聚性就越强。每个方法使用每个变量的类具有最大的内聚性。

一般来说,创建这种最大限度内聚的类既不可取,也不可能;另一方面,我们希望内聚力高。当内聚性高时,这意味着类的方法和变量是相互依赖的,并作为一个逻辑整体挂在一起。

保持函数小和参数列表短的策略有时会导致由方法子集使用的实例变量激增。当这种情况发生时,几乎总是意味着至少有一个其他类试图从较大的类中退出。您应该尝试将变量和方法分离到两个或多个类中,以便新类更具内聚性。

提高内聚性和降低耦合确实会带来好的软件设计。

内聚对功能进行了划分,使其简洁并与相关数据最接近,而解耦则确保功能实现与系统的其余部分隔离。

解耦允许您在不影响软件其他部分的情况下更改实现。

内聚性确保实现更特定于功能,同时更容易维护。

减小耦合、提高内聚的最有效方法是采用界面设计。

也就是说,主要的功能对象只能通过它们实现的接口相互“认识”。接口的实现自然会引入内聚性。

虽然在某些场景中不太现实,但这应该是一个设计目标。

例子(非常粗略):

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.
    }
}

在软件工程中,内聚是指某个模块的元素属于一起的程度。因此,它是软件模块的源代码所表达的每个功能之间相关性的一种度量。

简单地说,耦合就是一个组件(再一次,想象一个类,尽管不一定)对另一个组件的内部工作方式或内部元素的了解程度,即它对另一个组件的了解程度。

我写了一篇关于这个的博客文章,如果你想用例子和图表来阅读更多的细节。我想它回答了你的大部分问题。

耦合=两个模块之间的交互/关系… 内聚=模块内两个元素之间的交互。

软件是由许多模块组成的。模块由元素组成。把一个模块看作一个程序。程序中的函数是一个元素。

在运行时,一个程序的输出被用作另一个程序的输入。这称为模块与模块之间的交互或流程与流程之间的通信。这也称为耦合。

在单个程序中,函数的输出被传递给另一个函数。这称为模块内元素的交互。这也被称为内聚。

例子:

耦合=两个不同家庭之间的交流…… 凝聚力=家庭中父亲、母亲和孩子之间的交流。