High Cohesion, Loose Coupling

Loose Coupling

We are living in a time where businesses and the people running them often change their mind. I won’t be going into details of why is that so, let’s just say it is a given, and let’s say they are right. It gives them the competitive edge when they are flexible. It is on us to provide that. We are witnessing a high demand for a maintainable software, software that can change easily over time, and where the most of the effort measured in time and people’s work on projects happens after the initial release…long after the initial release if you’re happy. Needless to say, if we want to software to succeed in the long run, we must set our own mindset towards a way, that will provide the businesses their much needed value in that long run.

I know the following is a bold statement, but, you cannot say this enough so that it doesn’t become true.

There is no silver bullet in software development.

The only thing that separates the good software from the bad one is the value of the software for the business at that particular point in time. In order to prolong the value of the software for a long period of time you have to make it respond easier to change.

How you achieve that is a completely different matter. It borderlines with art and being able to predict the future. But, the good thing is that there are a few guidelines that you can follow that can help you out.

Here, I try to put some light on two of those: cohesion and coupling…

High Cohesion

Cohesion in software engineering is the degree to which the elements of a certain module belong together(in our case that we are going to discuss here we are mostly interested in classes, so module = class, unless otherwise noted). Thus, it is a measure of how strongly related each piece of functionality expressed by the source code of a software module is.

There are several types of cohesion commonly found scattered trough the code around the globe. So, let’s take a look at the description of some of them going from worst to best.

Coincidental cohesion (worst)

Coincidental cohesion is when parts of a module are grouped arbitrarily; the only relationship between the parts is that they have been grouped together. An example of this could be a Utility class where elements are completely independent of each-other. Image 1 illustrates roughly how that would look with the elements in the class.

Low Cohesion (worst)
Image 1: Low Cohesion (worst)

Logical cohesion

Logical cohesion is when parts of a module are grouped because they are logically categorized to do the same thing, even if they are different by nature (e.g. grouping all mouse and keyboard input handling routines).

Temporal cohesion

Temporal cohesion is when parts of a module are grouped by when they are processed – the parts are processed at a particular time in program execution (e.g. a function which is called after catching an exception which closes open files, creates an error log, and notifies the user).

Procedural cohesion

Procedural cohesion is when parts of a module are grouped because they always follow a certain sequence of execution (e.g. a function which checks file permissions and then opens the file).

Communicational/informational cohesion

Communicational cohesion is when parts of a module are grouped because they operate on the same data (e.g. a module which operates on the same record of information).

Sequential cohesion

Sequential cohesion is when parts of a module are grouped because the output from one part is the input to another part like an assembly line (e.g. a function which reads data from a file and processes the data).

Functional cohesion (best)

Functional cohesion is when parts of a module are grouped because they all contribute to a single well-defined task of the module (e.g. Lexical analysis of an XML string).

Image 2: High cohesion (best)
Image 2: High cohesion (best)

One way of looking at cohesion in terms of OO is if the methods in the class are using any of the private attributes. Image 2 is one example of how a high-cohesion class would look like.

Using metrics such as LCOM4 (Lack of Cohesive Methods) in a software called Sonar, and “Relational cohesion measurement” in NDepend (a cool tool I described here before), you can identify classes that could be refactored. The reason you want to refactor methods or classes to be more cohesive is that it makes the code design simpler for others to use it.


There are a couple of very common cases that I can think of where methods are low in “cohesiveness”:

  • Case 1: Method is not related to the class at all
  • Case 2: Utility Class
  • Case 3: Hidden objects and subclasses

It is not always possible to achieve the absolute high-cohesion in a class, but knowing what it is and how it contributes to the overall design can be a good knowledge. We cannot always make perfect, but we can at least strive for it.

1:    class HighCohesion  
2:    {  
3:      private int _elementA;  
4:      private int _elementB;  
6:      public int MethodA()  
7:      {  
8:        var returnValue = SomeOtherMethod(_elementA);  
9:        return SomeVeryOtherMethod(_elementB);  
10:      }  
12:      public void PrintValues()  
13:      {  
14:        Console.WriteLine(_elementA);  
15:        Console.WriteLine(_elementB);  
16:      }  
17:    }  

The point is having a the classes as small as possible in terms of elements. The less elements we have the greater the possibility for them to be used in all the methods.


Loose Coupling

Coupling (in software engineering) in simple words, is how much one component (again, imagine a class, although not necessarily) knows about the inner workings or inner elements of another one, i.e. how much knowledge it has of the other component.

Loose coupling is a method of interconnecting the components in a system or network so that those components, depend on each other to the least extent practically possible…

Tight coupling is where components are so tied to one another, that you cannot possibly change the one without changing the other.

In this StackOverflow question there is an answer that gives a funny but quite correct and clear description of what 1:1 coupling is:

iPods are a good example of tight coupling: once the battery dies you might as well buy a new iPod because the battery is soldered fixed and won’t come loose, thus making replacing very expensive. A loosely coupled player would allow effortlessly changing the battery.

The same, 1:1, goes for software development.

We will look at a drawing of the both.

Tight Coupling
Image 3: Tight Coupling

If we look at Image 3. It shows us a relation between two classes that is called tight coupling. Class1 above directly instantiates objects of Class2, and even goes as far as accessing member variables and so on. This makes it very dependent on Class2. What if we decided we wanted to add extra parameter in Class2’s constructor and make the default one private? Then we would have to change every usage of Class2 everywhere. Not so nice, heh? Potentially a very big headache and a one of the first places to look for problems in design.

Here is a code example of the illustration above:

1:    class ClassA  
2:    {  
3:      private bool _elementA;  
5:      public int MethodA()  
6:      {  
7:        if (_elementA)  
8:          return new ClassB()._elementB;  
10:        return 0;  
11:      }  
13:      public void PrintValues()  
14:      {  
15:        new ClassB().MethodB();  
16:      }  
17:    }  
19:    class ClassB  
20:    {  
21:      public int _elementB;  
23:      public void MethodB()  
24:      {  
25:        Console.WriteLine(_elementB);  
26:      }  
27:    }  

Do not despair!!! There is a solution!

The way we can solve this is by so called inverting the dependencies, by adding another layer. Example in C# would be adding an interface. That’s way Class1 will only be dependent on the interface, and not the actual implementation of Class2. Image 4 illustrates this point.

Loose Coupling
Image 4: Loose Coupling

Instantiation of the actual implementation will take place somewhere else in the code. Preferably main(or something like that) that deals exactly with this. This is the one of the most important reasons why dependency injection frameworks are being used.


Code example:

1:  class ClassA  
2:    {  
3:      private readonly ISomeInterface _interfaceImpl;  
5:      public ClassA(ISomeInterface interfaceImpl)  
6:      {  
7:        _interfaceImpl = interfaceImpl;  
8:      }  
10:      public int MethodA()  
11:      {  
12:        return _interfaceImpl.MethodB();  
13:      }  
15:      public void PrintValues()  
16:      {  
17:        _interfaceImpl.PrintValues();  
18:      }  
19:    }  
21:    interface ISomeInterface  
22:    {  
23:      int MethodB();  
24:      void PrintValues();  
25:    }  
27:    class ClassB : ISomeInterface  
28:    {  
29:      private int _elementB = 2 + 2;  
31:      public int MethodB()  
32:      {  
33:        return _elementB;  
34:      }  
36:      public void PrintValues()  
37:      {  
38:        Console.WriteLine(_elementB);  
39:      }  
40:    }  

What is the reason behind this, you may ask yourselves???……..Change.

When we have the components this separate, then we can have separate implementation of different problem areas. With separate implementation we can change as much as we want without breaking some other greater process that is using it. Furthermore, when you can change components independently, there is nothing stooping you from developing them independently and even deploy them separately. Maybe take it even one step further, imagine if the interface in the above example was a service that you invoke remotely. We will come back to the subject in some future post, but for now consider it as a possibility.

Now lets take a look at a special case of loose coupling.

Law of Demeter

The Law of Demeter (LoD) or the principle of least knowledge is a object-oriented software design principle. In its general form, the LoD is a specific case of loose coupling.

The formal object form of the law can be summarized as:

A method of an object may only call methods of:

  • The object itself.
  • An argument of the method.
  • Any object created within the method.
  • Any direct properties/fields of the object.

The conclusion can be summarized in one sentence:

Don’t talk to strangers!

An object A can request a service (call a method) of an object instance B, but object A should not “reach through” object B to access yet another object, C, to request its services. Doing so would mean that object A implicitly requires greater knowledge of object B’s internal structure. Instead, B’s interface should be modified if necessary so it can directly serve object A’s request, propagating it to any relevant subcomponents. Alternatively, A might have a direct reference to object C and make the request directly to that. If the law is followed, only object B knows its own internal structure.

In particular, an object should avoid invoking methods of a member object returned by another method , like for example:

var a = someObject.FirstMethod().SecondMethod();

For many modern object oriented languages that use a dot as field identifier, the law can be stated simply as “use only one dot”. The above example breaks the law where for example:

var a = someObject.Method();

does not. As an analogy(Wikipedia), when one wants a dog to walk, one does not command the dog’s legs to walk directly; instead one commands the dog which then commands its own legs.

The advantage of following the Law of Demeter is that the resulting software tends to be more maintainable and adaptable. Since objects are less dependent on the internal structure of other objects, object containers can be changed without reworking their callers.

Well, I hope some of you good people out there find this useful sometime in your lives 🙂

Until next time…Happy coding!