Tight coupling means classes and objects are dependent on one another. In general, tight coupling is usually not good because it reduces the flexibility and re-usability of the code while Loose coupling means reducing the dependencies of a class that uses the different class directly.
Tight Coupling
- The tightly coupled object is an object that needs to know about other objects and is usually highly dependent on each other's interfaces.
- Changing one object in a tightly coupled application often requires changes to a number of other objects.
- In the small applications, we can easily identify the changes and there is less chance to miss anything. But in large applications, these inter-dependencies are not always known by every programmer and there is a chance of overlooking changes.
Example
class A { public int a = 0; public int getA() { System.out.println("getA() method"); return a; } public void setA(int aa) { if(!(aa > 10)) a = aa; } } public class B { public static void main(String[] args) { A aObject = new A(); aObject.a = 100; // Not suppose to happen as defined by class A, this causes tight coupling. System.out.println("aObject.a value is: " + aObject.a); } }
In the above example, the code that is defined by this kind of implementation uses tight coupling and is very bad since class B knows about the detail of class A, if class A changes the variable 'a' to private then class B breaks, also class A's implementation states that variable 'a' should not be more than 10 but as we can see there is no way to enforce such a rule as we can go directly to the variable and change its state to whatever value we decide.
Output
aObject.a value is: 100
Loose Coupling
- Loose coupling is a design goal to reduce the inter-dependencies between components of a system with the goal of reducing the risk that changes in one component will require changes in any other component.
- Loose coupling is a much more generic concept intended to increase the flexibility of the system, make it more maintainable and makes the entire framework more stable.
Example
class A { private int a = 0; public int getA() { System.out.println("getA() method"); return a; } public void setA(int aa) { if(!(aa > 10)) a = aa; } } public class B { public static void main(String[] args) { A aObject = new A(); aObject.setA(100); // No way to set 'a' to such value as this method call will // fail due to its enforced rule. System.out.println("aObject value is: " + aObject.getA()); } }
In the above example, the code that is defined by this kind of implementation uses loose coupling and is recommended since class B has to go through class A to get its state where rules are enforced. If class A is changed internally, class B will not break as it uses only class A as a way of communication.
Output
getA() method aObject value is: 0