Loose Coupling and Tight Coupling in Java

In this article you will learn about loose coupling and tight coupling in java.

In simple words “Coupling is the degree of dependency between the modules or Routines.” 

“In a software or program, the more modules or classes will communicate with each other means the more tightly they are coupled and on other hand, the less they communicate with each other, means the more loosely they are coupled. “

Should the modules of a software tightly coupled or loosely?

So while developing software, we should design the modules as loosely coupled as we can. Because if each module of the software is loosely coupled with another then we don’t need to modify a module when in another module modification is required. On other hand, if the modules are tightly coupled with each other then to modify one module we have to modify another modules too which are dependent on the module we want to modify.

Coupling in Java

Loose Coupling and Tight Coupling in Java

Image Source

So if we see coupling in terms of Java, Where an object is being used by another object is known as Coupling. In this case an object will be dependent on another object to complete its tasks, means both of the objects are dependent on each other.

Tight Coupling

When some classes highly require one other to perform their functionality. For example, You have some functions in base class and you are inheriting it in other classes. So the derived class is highly dependent on the base class. if anything changes in base class will affect derived class too.

Example:

Let’s say there is a Control Room where we can manage the machines. So currently there are two machines Machine1 and Machine2.

Below is the program of  Control Room. Where in ControlRoom class, we have created objects of Machine1 and Machine2 classes and called their start method in manageMachine method. So by this way we’re starting the Machines from Control Room.

Let’s have a look on code:

/*
 * Example of Tight Coupling
 */

class ControllerRoom {

	Machine1 m1;
	Machine2 m2;

	public ControllerRoom(Machine1 m1, Machine2 m2) {
		this.m1 = m1;
		this.m2 = m2;
	}
	public void manageMachine() {
		m1.start();
		m2.start();
	}
}
class Machine1 {
	public void start() {
		System.out.println("Machine 1 Running");
	}
}
class Machine2 {
	public void start() {
		System.out.println("Machine 2 Running");
	}
}
public class Test {

	public static void main(String[] args) {
		Machine1 m1 = new Machine1();
		Machine2 m2 = new Machine2();
		ControllerRoom cr = new ControllerRoom(m1, m2);
		cr.ManageMachine();

	}
}

Output:

Machine 1 Running

Machine 2 Running

Everything is fine till yet. But let’s say, there is a requirement for one more machine. So its easy to do right? All we have to do is create one more class with the name Machine3.

class Machine3 {
	public void start() {
		System.out.println("Machine 3 is Running");
	}
}

Now we will add one extra object in ControllRoom, and we’ll also modify the constructor and manageMachine() method.

class ControllerRoom {

	Machine1 m1;
	Machine2 m2;
	Machine3 m3; //modified

	public ControllerRoom(Machine1 m1, Machine2 m2, Machine3 m3) {
		this.m1 = m1;
		this.m2 = m2;
		this.m3 = m3;  //modified
	}

	public void manageMachine() {
		m1.start();
		m2.start();
		m3.start(); //modified
	}
}

Have you noticed something?

Here the source code is tightly coupled because to add one extra machine Machine3, we had to modify an existing ControllerRoom class and according to OPEN CLOSED PRINCIPLE, a class should closed for modification and should be open for extension. So to add one more machine we should modify ControlRoom’s Code.

Loose Coupling

In terms of java, In Loose Coupling we try to reduce the dependencies of the class which uses another class in a direct way.

So let’s take the previous example:

class ControlRoom {

	IMachine machine;
	public ControlRoom(IMachine machine) {

		this.machine=machine;
		
	}

	public void manageMachine() {	
		
		this.machine.start();
	}

}

interface IMachine{
	void start();
	
}
class Machine1 implements IMachine{
	public void start() {
		System.out.println("Machine 1 is running");
	}

}

class Machine2 implements IMachine {
	public void start() {
		System.out.println("Machine 2 is running");
	}

}

class Machine3 implements IMachine{
	public void start() {
		System.out.println("Machine 3 is running");
	}
}


public class Test {

	public static void main(String[] args) {

		
		Machine1 m1 = new Machine1();
		ControlRoom cr = new ControlRoom(m1);
		cr.manageMachine();
		
		Machine2 m2 = new Machine2();
		ControlRoom cr2 = new ControlRoom(m2);
		cr2.manageMachine();
		
		Machine3 m3 = new Machine3();
		ControlRoom cr3 = new ControlRoom(m3);
		cr3.manageMachine();

	}
}

Output:

Machine 1 is running

Machine 2 is running

Machine 3 is running

In the above example, Now each time we need a new machine we’ll add a new class and will create the object of Machine3 in Test class but we do not need to modify ControlRoom class. That’s how loose coupling is done.

Conclusion

We should never write tightly coupled source code as it will take huge efforts and more maintenance time and that time can be reduced by writing loosely coupled code.

If you have any query or suggestion related to this article, then please let us know in comment section.

Leave a Comment

Your email address will not be published. Required fields are marked *