SoatDev IT Consulting
SoatDev IT Consulting
  • About us
  • Expertise
  • Services
  • How it works
  • Contact Us
  • News
  • July 19, 2023
  • Rss Fetcher
Photo by Redd F on Unsplash

Have you ever found yourself navigating multiple files to determine how a straightforward function behaves? On the other hand, have you ever been in the middle of a good class that does everything while you are struggling to add your minor improvement? If you have been here before, maybe the code you were exploring is tightly coupled and low in cohesion.

Thus, what exactly is tightly coupled and low in cohesion code? Why is tightly coupled and low in cohesion code bad? And how can you write better code?

To answer this question, let’s have a look at coupling and cohesion.

Coupling

In object oriented design, coupling refers to the degree of direct knowledge that one element has of another. In other words, how often do changes in class A force related changes in class B.

Let’s take a look at this code snippet:

public class Order {
private CashPayment payment = new CashPayment();

public void processPayment() {
payment.process();
}
}

public class CashPayment {
public void process() {
// Process logic
}
}

The Order class depends directly on the CashPayment class, which makes it difficult to modify the CashPayment class without affecting the Order class. In this case, we say Order class is tightly coupled with CashPayment class.

To make the code loosely coupled, we can introduce abstractions to the CashPayment class. Here is an updated version of the code:

public class Order {
private PaymentType payment;

public Order(PaymentType paymentType) {
payment = paymentType;
}

public void processPayment() {
payment.process();
}
}

public interface PaymentType {
public void process();
}

public class CashPayment implements PaymentType {
public void process() {
// Process logic
}
}

In the updated code, we introduced the PaymentType interface, which defines the process() method. The Order class now depends on the PaymentType interface instead of the concrete CashPayment class. By using an interface, we decouple the Order class from the specific implementation of the CashPayment class.

This change provides better flexibility. It also allows the Order class to work with any class that implements the PaymentType interface. In our case, we can easily add CreditCardPayement class without modifying the Order class.

To summarize, good code is loosely coupled because modifications will be made in the associated class.

Cohesion

In object-oriented design, cohesion refers to how a single class is designed. Cohesion is closely associated with making sure that a class is designed with a single, well-focused purpose. In other words, if the stuff that are grouped in a class tends to be similar in many aspects, then the class is said to have high cohesion.

Let’s take a look at this code snippet:

public class Circle {
private double radius;

public Circle(double radius) {
this.radius = radius;
}

public double getArea() {
return 3.14 * radius * radius;
}

public double getPerimeter() {
return 2 * 3.14 * radius;
}

public String toString() {
return "Circle (radius: " + radius + ")";
}

public void printDetails() {
System.out.println("Shape: " + this.toString());
System.out.println("Area: " + getArea());
System.out.println("Perimeter: " + getPerimeter());
}
}

The Circle class has an attribute radius, as well as methods for calculating the area, perimeter, and printing the details of the circle. However, the printDetails() method violates the principle of single responsibility by combining outputting details with calculating area and perimeter. We say our code is low in cohesion.

To improve cohesion, we can separate the responsibilities by creating a new class just for displaying the details of the circle:

public class Circle {
private double radius;

public Circle(double radius) {
this.radius = radius;
}

public double getArea() {
return 3.14 * radius * radius;
}

public double getPerimeter() {
return 2 * 3.14 * radius;
}

public String toString() {
return "Circle (radius: " + radius + ")";
}
}

public class CircleDetailsPrinter {
private Circle circle;

public CircleDetailsPrinter(Circle circle) {
this.circle = circle;
}

public void printDetails() {
System.out.println("Shape: " + circle.toString());
System.out.println("Area: " + circle.getArea());
System.out.println("Perimeter: " + circle.getPerimeter());
}
}

In the updated code, the CircleDetailsPrinter class is introduced to handle the printing of circle details. The Circle class now delegates the responsibility of printing to the CircleDetailsPrinter class.

By separating the printing functionality into its own class, we say that our code is highly cohesive. Each class has a single responsibility, which makes the code clearer and easier to maintain.

Note that in this example, cohesion is improved by separating the responsibilities between two classes. However, it’s important to establish a balance and avoid excessive class separation. The goal is to have focused classes with clear responsibilities without unnecessarily splitting them into too many small units.

Good code is highly cohesive because modifications will be made in the associated class.

Now that we understand the concept of cohesion, let’s apply what we have learned about coupling to the last example. We see that the CircleDetailsPrinter class is tightly coupled with the Circle class. Let’s decouple the CircleDetailsPrinter class from the specific implementation of the Circle class:

public interface Shape {
public double getArea();
public double getPerimeter();
}

public class Circle implements Shape {
// ...
}

public class Square implements Shape {
// ...
}

public class Rectangle implements Shape {
// ...
}

public class ShapeDetailsPrinter {
private Shape shape;

public ShapeDetailsPrinter(Shape shape) {
this.shape = shape;
}

public void printDetails() {
System.out.println("Shape: " + shape.toString());
System.out.println("Area: " + shape.getArea());
System.out.println("Perimeter: " + shape.getPerimeter());
}
}

By introducing the Shape interface, we decoupled the CircleDetailsPrinter class from the specific implementation of the Circle class. Additionally, we leverage the new ShapeDetailsPrinter class to serve the Square and Rectangle classes without duplicating code.

Conclusion

In conclusion, loosely coupled and high-cohesion code is the best. Additionally, we learned how hard it is to maintain tightly coupled and low-cohesion code and how to rework it.

I hope you found this article insightful. Thank you for reading.

Please make sure to follow me to get the updates.

You can also find me elsewhere on the internet.


Coupling and Cohesion in Object-Oriented Programming was originally published in Better Programming on Medium, where people are continuing the conversation by highlighting and responding to this story.

Previous Post
Next Post

Recent Posts

  • Naukri exposed recruiter email addresses, researcher says
  • Khosla Ventures among VCs experimenting with AI-infused roll-ups of mature companies
  • Presidential seals, ‘light vetting,’ $100,000 gem-encrusted watches, and a Marriott afterparty
  • Zoox issues second robotaxi software recall in a month following collision 
  • Landa promised real estate investing for $5. Now it’s gone dark.

Categories

  • Industry News
  • Programming
  • RSS Fetched Articles
  • Uncategorized

Archives

  • May 2025
  • April 2025
  • February 2025
  • January 2025
  • December 2024
  • November 2024
  • October 2024
  • September 2024
  • August 2024
  • July 2024
  • June 2024
  • May 2024
  • April 2024
  • March 2024
  • February 2024
  • January 2024
  • December 2023
  • November 2023
  • October 2023
  • September 2023
  • August 2023
  • July 2023
  • June 2023
  • May 2023
  • April 2023

Tap into the power of Microservices, MVC Architecture, Cloud, Containers, UML, and Scrum methodologies to bolster your project planning, execution, and application development processes.

Solutions

  • IT Consultation
  • Agile Transformation
  • Software Development
  • DevOps & CI/CD

Regions Covered

  • Montreal
  • New York
  • Paris
  • Mauritius
  • Abidjan
  • Dakar

Subscribe to Newsletter

Join our monthly newsletter subscribers to get the latest news and insights.

© Copyright 2023. All Rights Reserved by Soatdev IT Consulting Inc.