“低耦合和高内聚”意味着什么

时间:2012-12-22 06:57:35

标签: oop ooad

我在理解陈述low in coupling and high in cohesion时遇到了问题。我已经google了很多关于这个的内容,但仍然觉得很难理解。

据我所知,High cohesion意味着我们应该拥有专门用于执行特定功能的类。希望这是正确的吗?就像信用卡验证类一样,专门用于验证信用卡。

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

15 个答案:

答案 0 :(得分:194)

我相信这是:

Cohesion是指模块/类的元素在一起的程度,建议相关代码应该彼此接近,因此我们应该争取高内聚并将所有相关代码绑定在一起尽可能接近可能。它与模块/类中 元素有关。

耦合是指不同模块/类彼此依赖的程度,建议所有模块尽可能独立,这就是低耦合的原因。它与不同的模块/类中的元素有关。

想象整个图片会有所帮助:

enter image description here

截图来自Coursera

答案 1 :(得分:35)

软件工程中的凝聚力,就像在现实生活中一样,整体构成的元素(在我们的例子中是一个类)可以说它们实际上属于一个整体。因此,它是衡量软件模块源代码表示的每个功能的强烈关系的度量。

根据OO观察内聚的一种方法是,如果类中的方法使用任何私有属性。

现在讨论比这更大但是高凝聚力(或凝聚力的最佳类型 - 功能凝聚力)是模块的某些部分被分组,因为它们都有助于单个明确定义的任务模块。

耦合简单来说,一个组件(再次,想象一个类,虽然不一定)知道另一个组件的内部工作或内部元素,即它有多少知识另一个组成部分。

松散耦合是一种互连系统或网络中组件的方法,以便这些组件在实际可能的最小程度上相互依赖...

I wrote a blog post关于此事。它通过示例等详细讨论了所有这些。它还解释了为什么要遵循这些原则的好处。

答案 2 :(得分:19)

在软件设计中高凝聚力意味着课程应该做好一件事,一件事。高凝聚力与Single responsibility principle密切相关。

低耦合表明该类应该具有最少的可能依赖性。此外,必须存在的依赖关系应该是弱依赖关系 - 更喜欢依赖于接口而不是依赖于具体类,或者更喜欢组合而不是继承。

高内聚和低耦合为我们提供了更易于维护的设计代码。

答案 3 :(得分:9)

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

高凝聚力 - 将类似的东西放在一起。因此,一个班级应该有相关工作的方法或行为。举一个夸张的坏例子:List接口的实现不应该有与String相关的操作。 String类应该有方法,字段与String相关,同样,List的实现应该有相应的东西。

希望有所帮助。

答案 4 :(得分:7)

简短明确的答案

  • 高凝聚力:一个类/模块中的元素应该在功能上属于一个特定的东西。
  • 松散耦合:在不同的类/模块中应该是最小的依赖。

答案 5 :(得分:5)

长话短说,低耦合,因为据我所知它意味着组件可以换出而不会影响系统的正常运行。 Basicaly将您的系统模块化为可以单独更新的功能组件,而不会破坏系统

答案 6 :(得分:4)

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

答案 7 :(得分:1)

低耦合和高内聚是推荐的现象。

耦合意味着各种模块在何种程度上相互依赖,以及其他模块如何在更改模块的某些/相当大的功能时受到影响。强调低耦合因为必须保持较低的依赖性,以便对其他模块进行极少/可忽略的更改。

答案 8 :(得分:1)

示例可能会有所帮助。想象一个系统,它生成数据并将其放入数据存储,磁盘上的文件或数据库。

通过将数据存储代码与数据生产代码分开,可以实现高内聚。 (实际上将磁盘存储与数据库存储分开)。

低耦合可以通过确保数据生成没有任何不必要的数据存储知识来实现​​(例如,不要求数据存储有关文件名或数据库连接)。

答案 9 :(得分:1)

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

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

答案 10 :(得分:1)

凝聚力 - 一切都与彼此密切相关 耦合 - 所有内容如何相互连接。

让我们举一个例子 - 我们想设计一款自动驾驶汽车。

(1)我们需要电机正常运行。

(2)我们需要汽车自行驾驶。

(1)启动电机并使其运行的所有类别和功能都能很好地协同工作,但不能帮助汽车转向。所以我们将这些类放在引擎控制器后面。

(2)中的所有类别和功能都能很好地使汽车转向,加速和制动。他们没有帮助汽车启动或将汽油送到活塞。所以我们将这些类放在自己的驱动控制器之后。

这些控制器用于与所有可用的类和功能进行通信。然后控制器仅相互通信。这意味着我不能从油门踏板类中调用活塞级的功能,以使车速更快。

踏板类必须要求驾驶控制器与发动机控制器通信,然后发动机控制器告知活塞级别更快。这使我们程序员能够找到问题,并允许我们结合大型程序而不用担心。这是因为代码都在控制器后面工作。

答案 11 :(得分:1)

这是一个抽象的图形理论角度的答案:

通过仅查看有状态对象之间的(定向)依赖图来简化问题。

考虑两个limiting cases依赖图可以说明一个非常简单的答案:

第一种限制情况:a cluster graphs

簇图是高内聚和低耦合(给定簇尺寸)依赖图的最完美实现。

集群之间的依赖性最大(完全连接),集群间的依赖性最小(零)。

这是limiting cases之一中答案的抽象说明。

第二个极限情况是一个完全连接的图,其中所有内容都取决于所有内容。

在我的拙见中,现实介于两者之间,离集群图越近越好。

从另一个角度来看:当查看有向依存关系图时,理想情况下它应该是非循环的,否则循环将形成最小的群集/组件。

层次结构的上/下一步对应于松耦合,紧密内聚的“一个实例”,但是可以将这种松耦合/紧密内聚的原理视为在非循环有向图的不同深度处的重复现象(或在其中一棵生成树上)。

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

10个集群构成1个超集群,10个集群构成1个超集群,依此类推...如果没有紧密的凝聚力,松散耦合的概念,那么这种分层体系结构将是不可能的。

因此,这可能是故事的真正重要性,而不仅仅是两层中的高内聚性低耦合。在考虑更高级别的抽象及其交互时,真正的重要性变得显而易见。

答案 12 :(得分:0)

我认为您的定义太多了,但是如果您仍然有疑问,或者如果您是编程新手并且想要深入了解它,那么我建议您观看此视频, https://youtu.be/HpJTGW9AwX0 它只是获得更多有关多态性信息的参考... 希望您对此有了更好的了解

答案 13 :(得分:0)

低耦合:- 将使它非常简单。 如果您更改模块,它将如何影响其他模块。

示例:- 如果您的服务API公开为JAR,则对方法签名的任何更改都将中断调用API(高/紧耦合)。

如果您的模块和其他模块通过异步消息进行通信。只要收到消息,您的方法更改签名就将在模块本地(低耦合)。

在航线外,如果消息格式发生更改,则呼叫客户端将需要进行一些更改。

答案 14 :(得分:0)

以旧 PC 主板为例。

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

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

这是强/高耦合

由于鼠标仅用于操作光标和相关功能,键盘用于键入键等,即它们仅执行其预期的任务,这是高内聚

如果鼠标有几个按钮 'a' 'b' 'c' 可以输入,那么它做的比它应该做的要多,因为键盘已经在执行它们,这是 低内聚

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

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

“高内聚和松散耦合”