Loose coupling, tight coupling, decoupling – what is that all about?

Given that the *coupling family of keywords stands firmly in every software architect/designer vocabulary for over 20 years, it’s amazingly surprising how few people can tell the difference between tightly coupled and loosely coupled pieces of code.
If you ask a coder who comes from a Java-like universe to make an assessment of the degree of coupling of an example of code, they will start putting words interface and implementation in every single sentence. No doubt. But is that really the essence of the problem?

I propose a very simple Test of Coupling:

  1. Piece A of code is tightly coupled to Piece B of code if there exists any possible modification to the Piece B that would force changes in Piece A in order to keep correctness.
  2. Piece A of code is not tightly coupled to Piece B of code if there is no possible modification to the Piece B that would make a change to Piece A necessary.

Consider following example:


public class PieceB {
    private Dependency aDependency;
    public int countRelatedPiecesByColor(Color color) {
        System.out.println("Some text");
        return aDependency.call();
    }
}

...

public static void main(String[] args) {
    PieceB myDependency = new PieceB();
    int count = myDependency.countRelatedPiecesByColor(RED);
}
...

Line 12 with myDependency.countRelatedPiecesByColor(RED) is NOT tightly coupled to the body of the countRelatedPiecesByColor because there is no modification that can be made to it that would force us to change this line of code.
On the other hand the same line of code is tightly coupled to the signature of the countRelatedPiecesByColor method as for example the change of the name of this method would force a change to the line 12. Also, note that because of the latter line 12 is also tightly coupled to the type defined by PieceB, and let’s assume that without any formalisms.

Let’s consider also:

public interface UserRepository {

User find(String email);

}



public class UserHibernateRepository implements UserRepository {

        @Override
	public User find(String email) {
		return find(email, ANYWHERE);
	}

        //code omitted for conciseness

}

public static void main(String[] args) {
    UserRepository repository = MyApplicationContext.getActiveUserRepository();
    User marek = repository.find("marek.dec@example.com");
}

Here the repository.find(“marek.dec@example.com”) method call is once again tightly coupled to the signature of the invoked method and indirectly it is also tightly coupled to the type that defines the find method signature (i.e. UserInterface). Tight coupling can be also observed between the UserRepository interface and UserHibernateRepository class as any change to the find method signature will make a corresponding modification necessary.
There is no tight coupling between the find method body and the repository.find call – there is no modification you can make to the find method body that would force you to change the call. But what about the relation between the find method signature in the  UserHibernateRepository and line 22 in the example? Well, it turns out  if you want make a modification to it, you will have to change the implemented interface first and that would require a change to the repository.find call too.

So, does the extra interface, an extra level of abstraction buy you anything? Surely it does. Note that in the first example PieceB the line PieceB myDependency = new PieceB(); couples you tightly to the type named PieceB. You won’t  be allowed to take advantage of the fact the methods are virtual and  you will not be able to choose the implementations at runtime (do you have what to choose from?). But you are equally coupled to the methods bodies in both cases, and equally coupled to their signatures, not less and not more.

 

About these ads
  1. #1 by Viridium on January 15, 2014 - 10:24 pm

    OK, so if you use the Observer pattern and all you know about your listener is that it exposes a method called “someEventHappened” that you must call when needed, are you loosely coupled, or tightly coupled to your observer? Because if that method name changes, then your code is impacted by the change… I feel there’s something missing in your argument.

  2. #2 by Zardosht on June 16, 2014 - 8:57 am

    “If you ask a coder who comes from a Java-like universe to make an assessment of the degree of coupling of an example of code, they will start putting words interface and implementation in every single sentence. No doubt. But is that really the essence of the problem?”
    Honestly, I don’t have the feeling that you explained it better than them! Here is a better example: http://stackoverflow.com/a/227334/228965

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: