Low Coupling GRASP Pattern

Coupling is a measure of how strongly one element is connected to, has knowledge of, or relies on other elements. Low coupling is an evaluative pattern that dictates how to assign responsibilities to support
  • lower dependency between the classes
  • change in one class having a lower impact on other classes
  • higher reuse potential
Let's understand this pattern with what is the problem in existing code and how to provide a solution to it.

Problem

How to support low dependency, low change impact, and increase reuse?

Solution

Assign a responsibility so that coupling remains low.
A class, for example, with high (or strong) coupling relies on many other classes. Such classes may be undesirable; some suffer from the following problems:
  • Forced local changes because of changes in related classes.
  • Harder to understand in isolation.
  • Harder to reuse because its use requires the additional presence of the classes on which it is dependent.

Key points about low coupling

Good to know below are some key points about low coupling:
  • Low dependencies between “artifacts” (classes, modules, components).
  • There shouldn’t be too much of dependency between the modules, even if there is a dependency it should be via the interfaces and should be minimal.
  • Avoid tight-coupling for collaboration between two classes (if one class wants to call the logic of a second class, then first class needs an object of second class it means the first class creates an object of the second class).
  • Strive for loosely coupled design between objects that interact.
  • Inversion Of Control (IoC) / Dependency Injection (DI) - With DI objects are given their dependencies at creation time by some third party (i.e. Java EE CDI, Spring DI…) that coordinates each object in the system. Objects aren’t expected to create or obtain their dependencies—dependencies are injected into the objects that need them. The key benefit of DI—loose coupling.

Example

This is an example of loose coupling. Here we will demonstrate how to achieve loose coupling by applying dependency injection mechanism, the loose coupling implementation is achieved to allow start journey with any class which has implemented Vehicle interface.
Step 1: Vehicle interface to allow loose coupling implementation.
interface Vehicle {
    public void move();
}
Step 2: Car class implements Vehicle interface.
class Car implements Vehicle {
    @Override
    public void move() {
         System.out.println("Car is moving");
    }
}
Step 3: Bike class implements Vehicle interface.
class Bike implements Vehicle {
    @Override
    public void move() {
         System.out.println("Bike is moving");
    }
}
Step 4: Now create a Traveler class which holds the reference to the Vehicle interface.
class Traveler {
    private Vehicle v;
    public Vehicle getV() {
         return v;
    }
    public void setV(Vehicle v) {
        this.v = v;
    }

    public void startJourney() {
         v.move();
    }
}
Step 5: Test class for loose coupling example - Traveler is an example of loose coupling.
public static void main(String[] args) {
    Traveler traveler = new Traveler();
    traveler.setV(new Car()); // Inject Car dependency
    traveler.startJourney(); // start journey by Car
    traveler.setV(new Bike()); // Inject Bike dependency
    traveler.startJourney(); // Start journey by Bike
}

Reference


Comments