Object Oriented Programming

Do You Know the Tight and Loose Coupling in the Oop?

Your possible next interview question is on object-oriented programming.

Vikram Gupta
Javarevisited

--

Tight and Loose Coupling

While learning java programming you might have come across the concept of loose and tight coupling. When I was searching on the web for java interview questions I found this very commonly asked. Many of them have tried to explain in their own way using different examples. But the degree of differences between answers written over the web shows why it would be a difficult concept to grasp but I’ll be discussing it and will try to explain it in the easiest language.

What Is a Tight and Loose Coupling?

Tight coupling means when a group of classes are highly dependent on one another. This scenario arises when a class assumes too many responsibilities, or when one concern is spread over many classes rather than having its class.

Loose coupling is achieved using a design that promotes single responsibility and separation of concerns. A loosely coupled class can be consumed and tested independently of other classes.

How to Achieve Loose Coupling?

Interfaces are a powerful tool to use for loose coupling or decoupling. Classes can communicate through interfaces rather than other concrete classes.

Let’s see an example in Java programming that how we can achieve loose coupling.

1. Tightly Coupled:

Tightly coupled code relies on a concrete implementation. If we need a list of strings then we can do the following:

ArrayList<String> myList = new ArrayList<String>();

then this implementation is dependent on the ArrayList implementation.

2. Loosely Coupled:

If we want to change the implementation to loosely coupled code, then we refer to an interface (or other abstract) type.

List<String> myList = new ArrayList<String>();

Why Loosely Coupled Code Is Better Than Tightly Coupled?

List<String> myList = new ArrayList<String>();

The above loosely coupled implementation prevents us from calling any method using myList that's specific to the ArrayList implementation. We are limited to only those methods defined in the List interface. That means myList can access variables and methods of the List interface only and not any additional method defined in the ArrayList class.

If we decide later that we need a LinkedList instead of ArrayList, then we only need to change the code in one place, where we have created the new List, and not in 100 places where we have made calls to ArrayList methods.

Of course, we can instantiate an ArrayList using the first declaration and restrain ourselves from not using any methods that aren’t part of the List interface, but using the second declaration makes the compiler keep us honest.

Now Let’s See a Practical Example to Understand It Better:

IMachine Interface:

public interface IMachine {
void powerOn();

void powerOff();
}

Machine class implementing IMachine:

public class Machine implements IMachine {
public void powerOn() {
System.out.printf("Powering on Machine!!!");
}

public void powerOff() {
System.out.println("Powering Off Machine!!!");
}

public void reboot() {
System.out.println("Rebooting Machine!!!");
}
}

Driver class:

public class Driver {
public static void main(String[] args) {

//Tight coupling
Machine machine = new Machine();
//Calling methods on machine reference
machine.powerOn();
machine.reboot();
machine.powerOff();

//Loose coupling
IMachine iMachine = new Machine();
//Calling methods on iMachine reference
iMachine.powerOn();
/*
iMachine reference does not have visibility of reboot() method.
As it is not a part of IMachine interface.
*/
//iMachine.reboot();
iMachine.powerOff();
}
}

In the above example, there are two references created one using Machine class and the other using IMachine interface.

//Tight coupling
Machine machine = new Machine();

the above machine reference has visibility of all the methods of the Machine class and can access them.

//Loose coupling
IMachine iMachine = new Machine();

Whereas IMachine reference has visibility of all the methods of the IMachine interface and can access them but not the additional methods written in Machine class.

The advantage of using IMachine for creating reference variables is that, if later on in the development process, IMachine reference can point to some other concrete class that implements the IMachine interface.

Also, note that we only have to change at one place where this reference variable is assigned to an object and not every place where this reference variable is calling hundreds of methods in the application. So loose coupling helps in maintaining the code base and allows changes if needed in the future in the development process.

--

--

Vikram Gupta
Javarevisited

-: Empowering Developers to Ace Their Technical Interviews :-