内聚力和耦合之间的区别
内聚力和耦合力有什么区别?
耦合和内聚如何导致软件设计的好坏?
有哪些示例概述了两者之间的差异及其对整体代码质量的影响?
What is the difference between cohesion and coupling?
How can coupling and cohesion lead to either good or poor software design?
What are some examples that outline the difference between the two, and their impact on overall code quality?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(15)
内聚指的是类(或模块)可以做什么。低凝聚力意味着班级会采取各种各样的行动——范围广泛,不专注于应该做的事情。高内聚意味着类专注于它应该做的事情,即只关注与类意图相关的方法。
低内聚示例:
高内聚示例:
至于耦合,它指的是两个类/模块彼此之间的相关或依赖程度。对于低耦合类,更改一个类中的主要内容不应影响另一个类。高耦合会使代码难以更改和维护;由于课程紧密结合在一起,做出改变可能需要对整个系统进行改造。
好的软件设计具有高内聚和低耦合。
Cohesion refers to what the class (or module) can do. Low cohesion would mean that the class does a great variety of actions - it is broad, unfocused on what it should do. High cohesion means that the class is focused on what it should be doing, i.e. only methods relating to the intention of the class.
Example of Low Cohesion:
Example of High Cohesion:
As for coupling, it refers to how related or dependent two classes/modules are toward each other. For low coupled classes, changing something major in one class should not affect the other. High coupling would make it difficult to change and maintain your code; since classes are closely knit together, making a change could require an entire system revamp.
Good software design has high cohesion and low coupling.
模块内的高内聚和模块之间的低耦合通常被认为与面向对象编程语言的高质量有关。
例如,每个Java类内部的代码必须具有较高的内部内聚性,但与其他Java类中的代码尽可能松散耦合。
Meyer 的面向对象的软件构建(第 2 版) 的第 3 章对这些问题进行了精彩的描述。
High cohesion within modules and low coupling between modules are often regarded as related to high quality in OO programming languages.
For example, the code inside each Java class must have high internal cohesion, but be as loosely coupled as possible to the code in other Java classes.
Chapter 3 of Meyer's Object-Oriented Software Construction (2nd edition) is a great description of these issues.
内聚表明软件元素的职责的相关性和集中程度。
耦合是指软件元素与其他元素连接的强度。
软件元素可以是类、包、组件、子系统或系统。在设计系统时,建议使用具有高内聚并支持低耦合的软件元素。
内聚力低会导致类难以维护、理解并降低可重用性。同样,高耦合会导致类紧密耦合,并且更改往往不是非本地的、难以更改并减少重用。
我们可以假设一个场景,我们正在设计一个典型的可监控
ConnectionPool
,并满足以下要求。请注意,对于像ConnectionPool
这样的简单类来说,它可能看起来太多了,但基本目的只是为了用一些东西来演示低耦合和高内聚简单的例子,我认为应该有帮助。在低内聚的情况下,我们可以通过将所有这些功能/职责强制填充到一个类中来设计一个
ConnectionPool
类,如下所示。我们可以看到这个类负责连接管理、与数据库交互以及维护连接统计信息。通过高内聚,我们可以在各个类之间分配这些职责,并使其更易于维护和重用。
为了演示低耦合,我们将继续使用上面的高内聚
ConnectionPool
图。如果我们看一下上图,虽然它支持高内聚,但ConnectionPool
与ConnectionStatistics
类紧密耦合,并且PersistentStore
直接与它们交互。为了减少耦合,我们可以引入一个ConnectionListener接口,让这两个类实现该接口,并让它们向ConnectionPool类注册。ConnectionPool
将循环访问这些侦听器,并通知它们连接获取和释放事件,并减少耦合。注释/文字或警告:对于这个简单的场景,它可能看起来有些过大,但如果我们想象一个实时场景,我们的应用程序需要与多个第三方服务交互完成交易:直接将我们的代码与第三方服务耦合意味着第三方服务中的任何更改都可能导致我们的代码在多个位置发生更改,相反,我们可以使用
Facade
与这些服务进行交互内部有多个服务,对服务的任何更改都会成为Facade
的本地内容,并强制与第三方服务实现低耦合。Cohesion is an indication of how related and focused the responsibilities of an software element are.
Coupling refers to how strongly a software element is connected to other elements.
The software element could be class, package, component, subsystem or a system. And while designing the systems it is recommended to have software elements that have High cohesion and support Low coupling.
Low cohesion results in monolithic classes that are difficult to maintain, understand and reduces re-usablity. Similarly High Coupling results in classes that are tightly coupled and changes tend not be non-local, difficult to change and reduces the reuse.
We can take a hypothetical scenario where we are designing an typical monitor-able
ConnectionPool
with the following requirements. Note that, it might look too much for a simple class likeConnectionPool
but the basic intent is just to demonstrate low coupling and high cohesion with some simple example and I think should help.With low cohesion we could design a
ConnectionPool
class by forcefully stuffing all this functionality/responsibilities into a single class as below. We can see that this single class is responsible for connection management, interacting with database as well maintaining connection stats.With high cohesion we can assign these responsibility across the classes and make it more maintainable and reusable.
To demonstrate Low coupling we will continue with the high cohesion
ConnectionPool
diagram above. If we look at the above diagram although it supports high cohesion, theConnectionPool
is tightly coupled withConnectionStatistics
class andPersistentStore
it interacts with them directly. Instead to reduce the coupling we could introduce aConnectionListener
interface and let these two classes implement the interface and let them register withConnectionPool
class. And theConnectionPool
will iterate through these listeners and notify them of connection get and release events and allows less coupling.Note/Word or Caution: For this simple scenario it may look like an overkill but if we imagine a real-time scenario where our application needs to interact with multiple third party services to complete a transaction: Directly coupling our code with the third party services would mean that any changes in the third party service could result in changes to our code at multiple places, instead we could have
Facade
that interacts with these multiple services internally and any changes to the services become local to theFacade
and enforce low coupling with the third party services.简而言之,内聚表示代码库的一部分形成逻辑上单个原子单元的程度。另一方面,耦合表示单个单元对其他单元的依赖程度。换句话说,它是两个或多个单元之间的连接数量。数量越少,耦合度越低。
本质上,高内聚意味着将代码库中彼此相关的部分保留在一个地方。同时,低耦合是指尽可能地分离代码库中不相关的部分。
从内聚和耦合角度来看的代码类型:
理想是遵循准则的代码。它是松散耦合且高度内聚的。我们可以用这张图片来说明这样的代码:
God Object 是引入高内聚和高耦合的结果。它是一种反模式,基本上代表一段代码可以同时完成所有工作:
当不同类或模块之间的边界选择不当时,就会发生选择不当
破坏性解耦是最有趣的一种。当程序员试图将代码库解耦得太多以至于代码完全失去焦点时,有时会发生这种情况:
了解更多此处
simply, Cohesion represents the degree to which a part of a code base forms a logically single, atomic unit. Coupling, on the other hand, represents the degree to which a single unit is dependent on others. In other words, it is the number of connections between two or more units. The fewer the number, the lower the coupling.
In essence, high cohesion means keeping parts of a code base that are related to each other in a single place. Low coupling, at the same time, is about separating unrelated parts of the code base as much as possible.
Types of code from a cohesion and coupling perspective:
Ideal is the code that follows the guideline. It is loosely coupled and highly cohesive. We can illustrate such code with this picture:
God Object is a result of introducing high cohesion and high coupling. It is an anti-pattern and basically stands for a single piece of code that does all the work at once:
poorly selected takes place when the boundaries between different classes or modules are selected poorly
Destructive decoupling is the most interesting one. It sometimes occurs when a programmer tries to decouple a code base so much that the code completely loses its focus:
read more here
增加内聚性和减少耦合确实会带来良好的软件设计。
内聚对您的功能进行分区,使其简洁且最接近与其相关的数据,而解耦则确保功能实现与系统的其余部分隔离。
解耦允许您在不影响软件其他部分的情况下更改实现。
内聚确保实现功能更加具体,同时更易于维护。
减少耦合、增加内聚最有效的方法是按接口设计。
也就是说,主要的功能对象应该只通过它们实现的接口来“了解”彼此。接口的实现自然会引入内聚力。
虽然在某些情况下不现实,但它应该是一个可以遵循的设计目标。
示例(非常粗略):
在代码库的其他地方,您可以有一个模块来处理问题,无论它们是什么:
Increased cohesion and decreased coupling do lead to good software design.
Cohesion partitions your functionality so that it is concise and closest to the data relevant to it, whilst decoupling ensures that the functional implementation is isolated from the rest of the system.
Decoupling allows you to change the implementation without affecting other parts of your software.
Cohesion ensures that the implementation more specific to functionality and at the same time easier to maintain.
The most effective method of decreasing coupling and increasing cohesion is design by interface.
That is major functional objects should only 'know' each other through the interface(s) that they implement. The implementation of an interface introduces cohesion as a natural consequence.
Whilst not realistic in some senarios it should be a design goal to work by.
Example (very sketchy):
Somewhere else in your codebase, you could have a module that processes questions regardless of what they are:
对内聚的最好解释来自Uncle Bob的《干净的代码》:
类应该有少量的实例变量。类的每个方法都应该操作一个或多个这些变量。 一般来说,方法操作的变量越多,该方法与其类的内聚性就越高。每个方法使用每个变量的类是最大内聚的。
一般来说,创建这种最大内聚的类既不可取也不可能;另一方面,我们希望凝聚力较高。当内聚性很高时,意味着类的方法和变量是相互依赖的,并作为一个逻辑整体挂在一起。
保持函数较小和参数列表较短的策略有时会导致方法子集使用的实例变量的激增。当这种情况发生时,几乎总是意味着至少有一个其他班级试图脱离更大的班级。您应该尝试将变量和方法分成两个或多个类,以便新类更具凝聚力。
best explanation of Cohesion comes from Uncle Bob's Clean Code:
Classes should have a small number of instance variables. Each of the methods of a class should manipulate one or more of those variables. In general the more variables a method manipulates the more cohesive that method is to its class. A class in which each variable is used by each method is maximally cohesive.
In general it is neither advisable nor possible to create such maximally cohesive classes; on the other hand, we would like cohesion to be high. When cohesion is high, it means that the methods and variables of the class are co-dependent and hang together as a logical whole.
The strategy of keeping functions small and keeping parameter lists short can sometimes lead to a proliferation of instance variables that are used by a subset of methods. When this happens, it almost always means that there is at least one other class trying to get out of the larger class. You should try to separate the variables and methods into two or more classes such that the new classes are more cohesive.
软件工程中的内聚是指某个模块的元素所属的程度。因此,它是衡量软件模块源代码所表达的每项功能的相关程度的指标。
简而言之,耦合是一个组件(再次想象一个类,尽管不一定)对另一个组件的内部工作或内部元素了解多少,即它对另一个组件有多少了解。
我写了一篇关于此的博客文章,如果您想阅读带有示例和图纸的更多细节。我认为它回答了你的大部分问题。
Cohesion in software engineering is the degree to which the elements of a certain module belong together. Thus, it is a measure of how strongly related each piece of functionality expressed by the source code of a software module is.
Coupling in simple words, is how much one component (again, imagine a class, although not necessarily) knows about the inner workings or inner elements of another one, i.e. how much knowledge it has of the other component.
I wrote a blog post about this, if you want to read up in a little bit more details with examples and drawings. I think it answers most of your questions.
在软件设计中,内聚和耦合是关系到代码质量和可维护性的两个重要概念。
高内聚性:
低耦合:
In software design, cohesion and coupling are two important concepts related to the quality and maintainability of code.
High Cohesion:
Low Coupling:
我认为差异可以概括如下:
在这篇博文中,我更详细地介绍了它。
I think the differences can be put as the following:
In this blog post I write about it in more detail.
内聚表示模块的相对功能强度。
与程序其他部分中的其他组件进行交互。规定
简而言之,一个内聚模块应该(理想地)只做一件事。
„传统观点:
模块的“一心一意”
„OO观点:
„内聚意味着组件或类仅封装彼此密切相关以及与类或组件本身密切相关的属性和操作
„内聚级别
„功能性
„图层
„沟通
„顺序
„程序
„颞部
„效用
耦合是模块之间相对相互依赖性的指示。
耦合度取决于模块之间的接口复杂度,
对模块进行条目或引用的点以及哪些数据
跨接口传递。
传统观点:
组件与其他组件以及外部世界的连接程度
OO 视图:类之间连接程度的定性测量
耦合级别
„内容
„常见
„控制
„邮票
„数据
„例行调用
„类型使用
„包含或导入
„外部#
Cohesion is an indication of the relative functional strength of a module.
interaction with other components in other parts of a program. Stated
simply, a cohesive module should (ideally) do just one thing.
Conventional view:
the “single-mindedness” of a module
OO view:
cohesion implies that a component or class encapsulates only attributes and operations that are closely related to one another and to the class or component itself
Levels of cohesion
Functional
Layer
Communicational
Sequential
Procedural
Temporal
utility
Coupling is an indication of the relative interdependence among modules.
Coupling depends on the interface complexity between modules, the
point at which entry or reference is made to a module, and what data
pass across the interface.
Conventional View :
The degree to which a component is connected to other components and to the external world
OO view: a qualitative measure of the degree to which classes are connected to one another
Level of coupling
Content
Common
Control
Stamp
Data
Routine call
Type use
Inclusion or import
External #
内聚这个术语在软件设计中的含义确实有点违反直觉。
内聚力的通俗含义是指某种东西能很好地粘在一起、团结在一起,其特点是像分子吸引力一样具有很强的键合力。然而在软件设计中,这意味着争取一个理想情况下只做一件事的类,因此甚至不涉及多个子模块。
或许我们可以这样想。当一个部分是唯一的部分(只做一件事并且不能进一步分解)时,它具有最大的凝聚力。这正是软件设计所需要的。内聚只是“单一责任”或“关注点分离”的另一个名称。
术语耦合非常直观,这意味着当一个模块不依赖于太多其他模块并且它所连接的模块可以轻松替换时,例如遵守liskov替换原则 。
The term cohesion is indeed a little counter intuitive for what it means in software design.
Cohesion common meaning is that something that sticks together well, is united, which are characterized by strong bond like molecular attraction. However in software design, it means striving for a class that ideally does only one thing, so multiple sub-modules are not even involved.
Perhaps we can think of it this way. A part has the most cohesion when it is the only part (does only one thing and can't be broken down further). This is what is desired in software design. Cohesion simply is another name for "single responsibility" or "separation of concerns".
The term coupling on the hand is quite intuitive which means when a module doesn't depend on too many other modules and those that it connects with can be easily replaced for example obeying liskov substitution principle .
耦合 = 两个模块之间的交互/关系...
内聚 = 模块内两个元素之间的交互。
一个软件是由很多模块组成的。模块由元素组成。将模块视为程序。程序中的函数是一个元素。
在运行时,一个程序的输出用作另一个程序的输入。这称为模块到模块交互或进程到进程通信。这也称为耦合。
在单个程序中,一个函数的输出被传递给另一个函数。这称为模块内元素的交互。这也称为内聚力。
示例:
耦合 = 两个不同家庭之间的沟通...
凝聚力 = 家庭中父亲、母亲、孩子之间的沟通。
Coupling = interaction / relationship between two modules...
Cohesion = interaction between two elements within a module.
A software is consisting of many modules. Module consists of elements. Consider a module is a program. A function within a program is a element.
At run time, output of a program is used as input for another program. This is called module to module interaction or process to process communication. This is also called as Coupling.
Within a single program, output of a function is passed to another function. This is called interaction of elements within a module. This is also called as Cohesion.
Example:
Coupling = communication in between 2 different families...
Cohesion = communication in between father-mother-child within a family.
简单地说,内聚意味着一个类应该代表一个单一的概念。
如果所有类功能都与类所代表的概念相关,则类的公共接口是内聚的。
例如,不是使用 CashRegister 类,而是使用 CashRegister 和 Coin 功能内聚使其分为 2 个类 - CashRegister 和 Coin 类。
在耦合中,一个类依赖于另一个类,因为它使用该类的对象。
高耦合的问题是它会产生副作用。一个类中的一项更改可能会导致另一个类中出现意外错误,并可能破坏整个代码。
一般来说,高内聚、低耦合被认为是高质量的OOP。
Simply put, cohesion means that a class should represent a single concept.
The public interface of a class is cohesive if all the class features are related to the concept that the class represents.
For example, instead of having CashRegister class, having CashRegister and Coin features cohesion makes it into 2 classes - CashRegister and Coin class.
In coupling, one class depends on another as it uses the objects of the class.
The problem with high coupling is that it can create side effects. One change in one class could cause an unexpected error in the other class and could break the whole code.
Generally, high cohesion and low coupling is considered high quality OOP.
理论差异
内聚 内
程序其他部分的组件。
其他模块的。
内聚性的分类
1.同时发生的 2.逻辑发生的 3.时间发生的 4.过程发生的 5.通信发生的 6.顺序发生的 7.功能
耦合的
Theory Difference
Cohesion
components in other parts of program.
of other module.
Classification of Cohesion
1.Coincidental 2.Logical 3.Temporal 4.Procedural 5.Communication 6.Sequential 7.Functional
Coupling
简单来说,
内聚是“一起改变的代码保持在一起”。
耦合是“对一个组件的更改需要对另一个组件的更改”。
内聚适用于边界内的代码,耦合适用于跨边界的代码。
如果内聚性强、耦合性低,那么系统是稳定的。这是微服务世界的口头禅。
不同类型的耦合:(从松散到强)
In simple terms,
Cohesion is "the code that changes together stays together".
Coupling is "a change to one component requires change to another component".
Cohesion applies to the code that is within a boundary and coupling applies to the code across the boundary.
A system is stable if cohesion is strong and coupling is low. This is the mantra in microservice world.
Different types of coupling: (from loose to strong)