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?
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?
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:
-------------------
| Staff |
-------------------
| checkEmail() |
| sendEmail() |
| emailValidate() |
| PrintLetter() |
-------------------
Example of High Cohesion:
----------------------------
| Staff |
----------------------------
| -salary |
| -emailAddr |
----------------------------
| setSalary(newSalary) |
| getSalary() |
| setEmailAddr(newEmail) |
| getEmailAddr() |
----------------------------
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.
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.
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 like ConnectionPool
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, the ConnectionPool
is tightly coupled with ConnectionStatistics
class and PersistentStore
it interacts with them directly. Instead to reduce the coupling we could introduce a ConnectionListener
interface and let these two classes implement the interface and let them register with ConnectionPool
class. And the ConnectionPool
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 the Facade
and enforce low coupling with the third party services.
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):
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 }
}
Some where else in your codebase you could have a module that processes questions regardless of what they are:
public class OtherModuleProcessor {
public void Process(List<IStackoverflowQuestion> questions) {
... process each question.
}
}
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.
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 independent from 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
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.
cohesion refers all about how a single class is designed. Cohesion is the Object Oriented principle most closely associated with making sure that a class is designed with a single, well-focused purpose. The more focused a class is, the cohesiveness of that class is more. The advantages of high cohesion is that such classes are much easier to maintain (and less frequently changed) than classes with low cohesion. Another benefit of high cohesion is that classes with a well-focused purpose tend to be more reusable than other classes.
In the above image, we can see that in low cohesion only one class is responsible to execute lots of job which are not in common which reduces the chance of re-usability and maintenance. But in high cohesion there is a separate class for all the jobs to execute a specific job, which result better usability and maintenance.
Cohesion (Co-hesion) : Co which means together, hesion which means to stick. The System of sticking together of particles of different substances.
For real-life example:
img Courtesy
Whole is Greater than the Sum of the Parts -Aristotle.
Cohesion is an ordinal type of measurement and is usually described as “high cohesion” or “low cohesion”. Modules with high cohesion tend to be preferable, because high cohesion is associated with several desirable traits of software including robustness, reliability, reusability, and understandability. In contrast, low cohesion is associated with undesirable traits such as being difficult to maintain, test, reuse, or even understand. wiki
Coupling is usually contrasted with cohesion. Low coupling often correlates with high cohesion, and vice versa. Low coupling is often a sign of a well-structured computer system and a good design, and when combined with high cohesion, supports the general goals of high readability and maintainability. wiki
I think the differences can be put as the following:
In this blog post I write about it in more detail.
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 .
Cohesion is an indication of the relative functional strength of a module.
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 #
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.
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.Coincidental 2.Logical 3.Temporal 4.Procedural 5.Communication 6.Sequential 7.Functional