我理解这种低耦合高内聚的说法有问题。我在谷歌上搜索并阅读了很多这方面的内容,但还是觉得很难理解。

我的理解是,高内聚意味着,我们应该有专门执行特定功能的类。希望这是正确的?比如信用卡验证类,它专门用于验证信用卡。

还是不明白低耦合是什么意思?


当前回答

以旧的PC主板为例。

鼠标有自己的PS/2端口。 打印机有自己的打印机端口。 显示器有自己的VGA端口。

这意味着特定的端口只能用于特定的设备,而不能用于其他设备。

这就是强/高耦合

由于鼠标仅用于操作光标和相关功能,键盘用于输入按键等,即它们只执行它们所要执行的任务,这就是高内聚性

如果鼠标需要输入一些“a”、“b”、“c”按钮,那么它所做的就超过了它应该做的,因为键盘已经在执行它们了,这就是低内聚

幸运的是,专有端口的过时用法被我们称为USB的标准(接口)所取代。这是松散/低耦合

看看这些物理属性,很明显这就是它应该有的样子,但在编写软件时,很容易忘记什么功能应该放在哪里,等等,因此作为一个提醒,在生活中的任何事情中,始终坚持:

“高内聚和松耦合”

其他回答

低耦合是在两个或多个模块的上下文中。如果一个模块中的变化导致其他模块中的许多变化,那么它们被称为高度耦合的。这就是基于接口的编程的用处。模块内的任何变化都不会影响其他模块,因为它们之间的接口(交互的平均值)没有改变。

高内聚性——把相似的东西放在一起。所以一个类应该有方法或行为来做相关的工作。举一个夸张的坏例子:List接口的实现不应该有与String相关的操作。String类应该有方法和与String相关的字段,类似地,List的实现应该有相应的东西。

希望这能有所帮助。

在软件设计中,高内聚性意味着类应该做一件事,并且把一件事做得很好。高凝聚力与单一责任原则密切相关。

低耦合意味着类应该具有最少的依赖关系。而且,必须存在的依赖关系应该是弱依赖关系——喜欢对接口的依赖而不是对具体类的依赖,或者喜欢组合而不是继承。

高内聚和低耦合使我们能够更好地设计代码,从而更容易维护。

你有智能手机吗?有一个大的还是很多小的应用程序?一个应用程序是否会回复另一个应用程序?您可以在安装、更新和/或卸载另一个应用程序时使用一个应用程序吗?每个应用程序都是独立的,这是一种高内聚性。每个应用程序都独立于其他应用程序,这是低耦合。DevOps偏爱这种架构,因为这意味着您可以在不中断整个系统的情况下进行离散的连续部署。

下面是一个从抽象的图论角度给出的答案:

让我们通过只查看有状态对象之间的(有向)依赖关系图来简化这个问题。

一个极其简单的答案可以通过考虑依赖图的两种限制情况来说明:

第一个极限情况:聚类图。

簇图是高内聚低耦合(给定一组簇大小)依赖图的最完美实现。

簇之间的依赖性是最大的(完全连接),而簇间的依赖性是最小的(零)。

这是一种极限情况下答案的抽象说明。

第二个极限情况是一个全连通图,其中所有东西都依赖于所有东西。

在我看来,现实情况介于两者之间,越接近聚类图越好。

从另一个角度来看:当观察有向依赖关系图时,理想情况下它应该是无循环的,如果不是,那么循环就会形成最小的集群/组件。

层次结构的上升/下降对应于软件中松耦合、紧密内聚的“一个实例”,但可以将这种松耦合/紧密内聚原则视为在无环有向图(或其生成树之一)的不同深度上的重复现象。

将系统分解为层次结构有助于克服指数级的复杂性(比如每个集群有10个元素)。在6层中,已经有100万个对象了:

10个星系团形成1个超星系团,10个超星系团形成1个超星系团……如果没有紧密内聚、松散耦合的概念,这样的层次结构就不可能实现。

所以这可能是故事的真正重要性,而不仅仅是两层中的高内聚低耦合。当考虑更高级别的抽象及其交互时,真正的重要性变得清晰起来。

继承或泛化是高耦合(即高度相互依赖)的一个例子。我这么说的意思是,在继承中,父类通常定义了它的子类使用的基本功能,父类方法的更改直接影响它的子类。因此,我们可以说,阶级之间有更大程度的相互依赖。

实现或使用接口是一个高内聚(即低相互依赖)的例子。这意味着接口为实现它的任何类提出了契约,但每个类都有权以自己的方式实现接口中声明的方法,并且一个类中声明的方法的更改不会影响任何其他类。