What is Cohesion?
Cohesion refers to the degree to which the elements inside a module, such as methods or functions in a class, belong together.
High cohesion, considered an attribute of well-designed software, helps in maintaining and understanding code as each module performs a single, well-defined task.
For instance, consider a "Calculator" class in an application.
If this class contains methods related only to mathematical operations, like 'add', 'subtract', 'multiply', 'divide', etc., it exhibits high cohesion since all methods contribute to a single, specific functionality of being a calculator.
High cohesion reduces complexity by limiting the amount of functionality each component has and increases the software's maintainability and readability.
It also bolsters robustness, as tightly related constituents lead to less error-prone and more predictable behavior.
Different Types of Cohesion in Software Engineering
There are several types of cohesion that are commonly used in software engineering. These include:
Functional cohesion is the highest level of cohesion where all elements of a module are aligned towards accomplishing a single, well-defined task.
Such high level of unity in purpose makes the module highly reliable and robust, thereby promoting code reusability.
In sequential cohesion, the elements of a module are interlinked such that the output from one element serves as the input for the next.
This type of cohesion establishes a pipeline where information passes from one process to another in a sequence.
Communicational cohesion is when operations within a module reference or manipulate the same input or output data.
Each operation may have a different purpose, but their cohesion comes from sharing the same data.
Procedural cohesion groups operations that must be executed in a specific order, often due to procedural or algorithmic dependencies.
These operations may not share the same data, and their connection stems from the sequence in which they must be performed.
Temporal cohesion pulls together operations that should be executed in the same time frame or in response to the same event.
For example, a module focusing on startup or shutdown processes can be said to exhibit temporal cohesion.
Logical cohesion is when the elements of a module are grouped because they logically fall under the same category, not because they contribute to a single task.
Often, a control flag is used to determine which operation of the module will be executed.
Coincidental cohesion is the lowest level of cohesion where elements have no meaningful relationship to each other—they just happen to be part of the same module.
This type of cohesion usually arises when unrelated tasks are pushed into a single module without any logical grouping.
Informational cohesion is when a module performs a number of functions, each with its own entry point, with independent inputs and outputs.
The only relationship is that all functions take the same input data.
Concurrent cohesion is a scenario where the module performs multiple independent functions concurrently.
The outputs depend on the independent activities but may not directly depend on the same input.
Hierarchical cohesion is when a module is broken down into sub-modules, each responsible for a part of the main module's function.
This kind of hierarchy can make complex systems easier to understand and manage.
In software engineering, striving for high cohesion is a good practice because it enhances the readability, maintainability, and reusability of the codebase while reducing the chances of bugs and errors.
What is Coupling?
Coupling is a concept in software engineering that refers to the degree to which the components of a system depend on each other.
Low coupling means that changes to one component have minimal impact on the other components. High coupling means that changes to one component can have a significant impact on the other components.
In software design, coupling is the extent to which the components of a system depend on each other.
Importance of Coupling in Software Engineering
Low coupling is an important design goal in software engineering, because it improves the modularity and flexibility of the system.
Different Types of Coupling in Software Engineering
There are several types of coupling that are commonly used in software engineering. These include:
Content Coupling, also known as Pathological Coupling, occurs when a module directly accesses or modifies another module's internal data or code.
This severely restricts maintainability and flexibility in the codebase.
Common Coupling transpires when multiple modules share access to global data, which can cause interdependence among modules, making the system more prone to changes cascade and harder to understand.
Control coupling occurs when one module controls the flow of another module by passing control information (e.g., flags, parameters). This type of coupling reduces readability and makes the system more rigid.
Stamp Coupling happens when modules share a composite data structure, requiring only parts of that structure for their specific function. This leads to a higher chance of data corruption and can make the code harder to debug.
Data Coupling arises when modules communicate through simple parameters or plain data types. A change in the data structure can affect the way modules share data, but this coupling is comparatively less restrictive than others.
External Coupling is the dependency on an external resource or system, such as a database, file, or third-party API.
Changes in the external system can affect the overall implementation and integration of those resources within your software.
Temporal Coupling transpires when two or more modules must execute in a specific order or within a specific time frame.
This can lead to difficulty in parallelizing tasks or testing individual components.
Subtype Coupling occurs when a module relies on a specific subtype, leading to an increased dependency upon that subtype.
This restricts flexibility in case a new subtype is introduced or the existing one is modified.
Procedural Coupling emerges when modules communicate through a predefined process or a sequence of calls, fostering a higher degree of dependency among modules, and risking a fragile system that can break under changes.
Layered Coupling refers to the interaction between modules in a hierarchical or layered architecture.
Though it's the desired form of coupling, it's essential to manage the dependencies to ensure maintainability and testability.
Relationship Between Cohesion & Coupling
The relationship between cohesion and coupling is important in software engineering, because it is often difficult to achieve both high cohesion and low coupling simultaneously.
There is an inverse relationship between cohesion and coupling.
Cohesion: The Inner Connectivity
Cohesion refers to the measure of how closely the tasks performed by a single module are related to each other.
The stronger the relationship, the higher the cohesion. High cohesion enhances understandability, maintainability, and reusability of code.
Coupling: The Interdependence
Coupling gauges the level of dependency between different software modules.
Lower coupling, indicating less dependency, is beneficial as it reduces the sensitivity to changes in other modules, and thus makes the system more robust and easy to manage.
Cohesion and Coupling: An Inverse Relationship
Cohesion and coupling share an inverse relationship in effective software design: the goal is to maximize cohesion within each module, while minimizing coupling between different modules.
This balance enhances the quality of software.
The Impact of Cohesion and Coupling
Cohesion ensures that a module is doing 'one thing', which makes it easier to understand, modify, and test.
On the other hand, low coupling decreases the risk of 'domino effect' changes, enhancing system stability.
Relevance of Cohesion and Coupling in Developments
Understanding and implementing principles of high cohesion and low coupling is critical in creating flexible, maintainable, and reliable software.
It helps drive decisions during design processes and boosts the overall quality of the software.
Cohesion & Coupling Metrics
Cohesion and coupling can be measured using various metrics. Measuring these metrics provides insights into the quality of the software system.
Lack of Cohesion of Methods (LCOM)
LCOM captures the lack of cohesion in a class by examining the mismatch between methods and instance variables.
A lower LCOM score implies higher cohesion, signaling that greater harmony exists among methods sharing the class's data.
Coupling Between Objects (CBO)
CBO is a measure of the number of classes a class is coupled with. Low CBO signifies minimal dependency and thus reduced complexity and increased maintainability.
A low CBO points towards a modular, decoupled system.
Message Passing Coupling (MPC)
MPC metric counts the total messages passed or information flows between modules, indicating the degree of interaction. Lesser the number, better the decoupling.
Data Abstraction Coupling (DAC)
DAC measures coupling in terms of abstract data types a class has in its interface. This metric reflects how complex class dependencies are.
Cohesion Among Class Methods (CAM)
CAM metric considers the intersection of types of method parameters in a class, providing an understanding of how well the methods within a class are related. Higher CAM values indicate better cohesion.
Response for a Class (RFC)
RFC combines the methods of a class and the methods called by them to quantify the amount of communication between classes. Lower RFC values are desirable as they signify less coupling and simpler testing.
This coupling metric examines how data is exchanged between different modules. Lower data coupling is better as it promotes encapsulation and reduces the overall complexity of communication between modules.
This metric measures the extent to which a module controls the flow of another. Reducing control coupling helps maintain modularity and independence among modules.
These metrics, among others, allow software developers to gauge the quality of their software designs and strive for high cohesion and low coupling – two hallmarks of well-designed, maintainable software.
Frequently Asked Questions (FAQs)
What is Cohesion in Software Engineering?
Cohesion in software engineering refers to how closely related elements of a module or component are. High cohesion systems have strongly related elements, while low cohesion systems do not.
What are the Benefits of High Cohesion?
Highly cohesive systems are easier to maintain and modify, less error-prone, provide flexibility and are easier to test. These provide high quality software products.
What is Coupling in Software Engineering?
Coupling in software engineering refers to how dependent the components of a system are on one another. Low coupling systems have components that can be changed with minimal impact on others.
Why is Low Coupling Desirable in Software Engineering?
Low coupling is desirable in software engineering as it makes systems more modular and flexible enabling components to be changed with minimal impact on others.
What are the Different Types of Cohesion?
The different types of cohesion, most commonly used in software engineering are: functional cohesion, sequential cohesion, communicational cohesion, procedural cohesion, temporal cohesion, logical cohesion and coincidental cohesion.