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 comonly 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 independend of eachother. Image 1 ilustrates 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;  
5:    
6:      public int MethodA()  
7:      {  
8:        var returnValue = SomeOtherMethod(_elementA);  
9:        return SomeVeryOtherMethod(_elementB);  
10:      }  
11:    
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 ralation 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 ilustration above:


1:    class ClassA  
2:    {  
3:      private bool _elementA;  
4:        
5:      public int MethodA()  
6:      {  
7:        if (_elementA)  
8:          return new ClassB()._elementB;  
9:          
10:        return 0;  
11:      }  
12:    
13:      public void PrintValues()  
14:      {  
15:        new ClassB().MethodB();  
16:      }  
17:    }  
18:    
19:    class ClassB  
20:    {  
21:      public int _elementB;  
22:    
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 ilustrates 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;  
4:    
5:      public ClassA(ISomeInterface interfaceImpl)  
6:      {  
7:        _interfaceImpl = interfaceImpl;  
8:      }  
9:    
10:      public int MethodA()  
11:      {  
12:        return _interfaceImpl.MethodB();  
13:      }  
14:    
15:      public void PrintValues()  
16:      {  
17:        _interfaceImpl.PrintValues();  
18:      }  
19:    }  
20:    
21:    interface ISomeInterface  
22:    {  
23:      int MethodB();  
24:      void PrintValues();  
25:    }  
26:    
27:    class ClassB : ISomeInterface  
28:    {  
29:      private int _elementB = 2 + 2;  
30:    
31:      public int MethodB()  
32:      {  
33:        return _elementB;  
34:      }  
35:    
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 idenpendently, there is nothing stoping you from develping 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 coulpling.

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 usefull sometime in your lives 🙂

Until next time…Happy coding!

Bojan

Advertisements

Posted by TheBoyan

I have been programming since I was 11 years old (Yes, I'm one of those, for real). First programming language I learned was BASIC, on a Commodore64. Then around high-school it was C and Assembly. Just before and during university days it was C++. I started doing some professional work during this period, part of the reason why I dropped out of uni in my final year. I have never stopped since then. Going through a plethora of technologies ranging from C and Assembly languages, Delphi to C++, C#, Java and so on and so forth... trough 20 (and more, who counts, does it even matter) years of software development. I have not lost even a single bit of my ambition and love for the craft from those first young days, nor the energy...I absolutely love what I do. I like to get my hands into all aspects of software development. Now-a-days I use mainly Microsoft related technologies .NET C#, with a lot of database design/management usage of SQL server, but not in any way limited to that.

20 Comments

  1. Great stuff, nothing new but great descriptions and analogies! Makes it easier to wrap your head around the concepts!

    Liked by 1 person

    Reply

  2. Very well said! Very relevant specially nowadays with this startup mindset of shipping fast and fixing later… Fixing later can be a really painful task if you didn’t pay attention to the points explained in this article.

    One point that it is worth mentioning is that you have be careful to not violate the Single Responsibility Principle (SRP) of OO when aiming for high cohesiveness.

    In my point of view, thinking about design should be business as usual for every developer. Not a separate and “expensive” task that demands time which, then, does not contribute with the “ship fast” mindset.

    Again, thanks for sharing!

    Liked by 1 person

    Reply

  3. Shilpi Agrawal April 16, 2015 at 1:08 am

    Hi ! Can you explain me how coupling and cohesion directly affect the trustworthiness (mainly security) of the software?

    Like

    Reply

    1. Well, Shilpi, it doesn’t directly affect security of the software. These are purely design principles, that help you design software that is flexible and easy to change. If you are concerned about security then there are other methodologies and principles that you can use, and they all depend on what you actually want to do in your project.

      /Bojan

      Like

      Reply

  4. It would be nice to keep in mind the original sources of these ideas, which were first published in 1979. FWIW, this book still holds a place of honor on my bookshelf, even though some of the examples are a bit dated (anyone remember tape drives)?

    http://www.amazon.com/Reliable-software-through-composite-design/dp/0884052842/ref=mt_hardcover?_encoding=UTF8&me=

    Liked by 1 person

    Reply

  5. Jaroslav Svestka January 5, 2016 at 12:12 am

    Thanks, very well said. Great pictures and analogies.

    Liked by 1 person

    Reply

  6. Great that you emphasized why these principles apply (change), and build the concepts from here. It keeps things so much better aligned when starting from first principles. Great article!

    Liked by 1 person

    Reply

  7. Thilina Samiddhi Jayathilaka March 15, 2016 at 6:47 am

    It is amazing to see how you have grasped these valuable concepts and I must thank you for helping junior programmers. I have a question about one of your statements. Please enlighten me and correct if I have any mistakes.

    Quote Starts :
    “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.”
    Quote Ends.

    I had the chance to use POJO classes, which are templates for relational model objects, in several java project in my studies. Some of those classes had 10-15 elements/attributes. Therefore obviously they had 20-30 getters and 20-30 setters for each attribute. IS THIS AN INSTANCE OF COINCIDENTAL COHESION (WORST) ?????

    Please explain. Thanks in advance.

    Like

    Reply

    1. Hej Thilina,

      Thanks for your nice comment.

      As for your question…It depends how you look at it…POJO classes are one form of data structures(data bearers sort of speak). So, they server a specific purpose of trasfering data or so. The cohesion/coupling principle is more aplicable if you look at classes that have functionality, i.e. classes that process the data. Classes to which the POJO clasess are very often input themselves.

      Hope this helps a little bit.

      Cheers,
      Bojan

      Liked by 1 person

      Reply

      1. Hi,
        Thanks a lot for clearing that out for me 🙂

        I found this site when i was searching about loose coupling and this was really helpful. I hope you could create really good posts in future too. Wish You all the best.

        Best Regard,
        Thilina Samiddhi

        Like

  8. You have excellent summarized. Thanks.

    Like

    Reply

  9. My first article in your site and you made me your fan. It was very informative and illustrations that you mentioned in between made things very clear.
    Generally techie people can’t write good and express nicely but you did a great job.
    Keep up the good work.

    Like

    Reply

    1. Thank you Abhishek! I greatly appreciate your nice comment!

      Like

      Reply

  10. It explained clearly, but do you think Which is desirable

    Like

    Reply

  11. It seems to me that high cohesion and low coupling are mutually exclusive ways of describing the relationship between any two data entities. Because it is impossible for any two entities to have both high cohesion and low coupling they are mutually exclusive. Perhaps the relationship between two data entities could be rated on a spectrum with high cohesion on one end and low coupling on the other. Data entities that have high cohesion make sense to be in the same class. If they have low coupling it makes sense for them to be in different classes. It seems like a very effective guide to how to arrange class hierarchies in a new software system design. Any new data entity will either have a high cohesion with existing classes or have low coupling. Where it falls on that spectrum will guide how it should be added to the hierarchy.

    Is this true in practice, or am I just inferring something that isn’t there?

    Like

    Reply

    1. According to Myers (https://www.amazon.com/Reliable-software-through-composite-design/dp/0884052842), the two are complementary:

      – Coupling refers to relationships between modules
      – Cohesion (Myers calls this “strength”) refers to relationships among elements within a module.

      Like

      Reply

  12. If you want to try different coupling methods to solve linear or nonlinear problems using different codes at the same time try Newton: github.com/fedecaccia/newton

    Like

    Reply

  13. Good article. I makes me think that the stream in Java 8 is violating the principle, is it?

    Like

    Reply

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