Cohesion, Coupling and Composition

Reading Time: 2 minutes

Cohesion

Cohesion indicates that the depth of the relation in between to sources or dependencies. This is not related to a practical coding, but a mentality that helps to write a better maintainable code. High Cohesion means clear separation of concerns, low cohesion is the reverse. To provide high cohesion in an application, we shall separate the concerns by their related areas.

For example Imagine an interface of a company taking care of all the processes

public interface MyCompany{

public void hireCandidates();
public void payTaxes();
public void cleanBuilding();

}

if we apply high cohesion then we will separate concerns and departments by their responsibilities;

public interface HRDepartment{
	public void hireCandidates();
}

public interface FinanceDepartment{
	public void payTaxes();
}

public interface JanitorDepartment{
	public void cleanBuilding();
}

Coupling

Coupling refers to how much a class or module knows about other classes or modules. If a class—say, Editor—interacts with another class—say, Author—by using its interface (public methods), then classes Editor and Author are loosely coupled. But if class
Editor can access and manipulate Author by using its nonpublic members, these classes are tightly coupled.

Tightly coupled

Author.java

class Author {
String name;
String skypeID;
public String getSkypeID() {
return skypeID;
}
}

Editor.java

class Editor{
public void clearEditingDoubts(Author author) {
setUpCall(author.skypeID);
converse(author);
}
void setUpCall(String skypeID) { /* */}
void converse(Author author) {/* */}
}

here the clearEditingDoubts method is tightly couple to the non public variable, if the name of variable is changed then the editor class won’t compile.

Here is the loosely coupled version of the example;

Editor.java

class Editor{
public void clearEditingDoubts(Author author) {
setUpCall(author.getSkypeID());
converse(author);
}
void setUpCall(String skypeID) { /* */}
void converse(Author author) {/* */}
}

Here as you see that if there is any change in the Author object then the Editor object wont be affected because the name is provided via the public method.

However, Interfaces also promote loose coupling across classes and modules. Assume that the entity Author is defined as an interface, which can be implemented by specialized authors such as TechnicalAuthor.

interface Author {
String getSkypeID();
}
class TechnicalAuthor implements Author{
String name;
String skypeName;
public String getSkypeID() {
return skypeName;
}
}
class Editor{
public void clearEditingDoubts(Author author) {
setUpCall(author.getSkypeID());
converse(author);
}
void setUpCall(String skypeID) { /* */}
void converse(Author author) {/* */}
}

This part of coupled topic has been copied from Mala Gupta’s OCP book

Composition

Composition simply corresponds to an object that composes of different objects in it, collecting all the required functionalities from those classes.

class Engine { /* code */ }
class Wheel { /* code */ }
class Car {
Engine engine;
Wheel[] wheels = new Wheel[5];
}

Simply in this sample code snippet, the car object will favor the functionalities from the instances of Engine and Wheel object. There is also another good of composition is to pick object composition over inheritance is a base class is fragile. A change made in the base class can have major effects on all of its derived classes.

Some of this content of the topic were derived from Mala Gupta’s OCP Book