Tips on how to improve cohesion in a software design

For the novice in object-oriented programming one of the biggest challenges faced is the new mindset introduced by the OO concept: to be able to think and to model the world in a set of objects and its respective methods.

Every time I take part on a project where the people working are not used to this programming style (using the Microsoft Solution Framework of course) I notice that the main question marks are: what to aggregate? what to specialize? What to move to a super-class? what to leave as module specific operation?

Why do the people have this problem?

IMHO and as far as my experience tells me, I would say 80% of these issues are related to the fact that they are no longer be using the terrible global variables in their programming. and we know how hard is to let go this bad habit once you are used to it and specially if they are coming from a language where the untyped variables can be freely used, as in the classic Visual Basic.

And because those guys now are not using global variables anymore the first effect we notice in the development metric the low cohesion. The cohesion is what is going to bind in the relationship between object and its own operations, making it (the object) responsible for their actions and at the same time not having to worry about who is going to be calling them (the methods). A high cohesion is generally a very nice thing to have, because it introduces a resposability layer that only the methods will be aware of it. For instance: the process of getting a value (i.e.: an account balance) can introduce a change in other places (i.e.: some internal counter limiting the number of requests per minute) and the caller should not bear the responsability of this change.

For these people and these cases I usually show a little trick that now I share with you guys.

1st: Think of the data and its operations like eternal lovers. They are always together in the same domain, they always walk around as a pair no matter where they go. As an exercise take a moment and put everything you are about to develop under a helicopter view, try to draw a diagram grouping the objects and its methods like the one below:

 



2nd - if you are using too many nested 'if', you probably should be using 'cases/switches'. If you are using too many 'cases/switches' you probably should create an enumerator for those values. If a value needs to be accessed from somewhere outside the scope, create a method just to return this value. This technique outlined here in the 2nd rule is proven to be a great public variable killer, thus helping to enforce a good cohesion.

Now, let's go to the cohesion point. Enumerate the objects you are going to deal. Enumerate the methods you are going to call. Draw a matrix with them in a way that you can see who (object) is calling who (methods), like the one below:

 



Cool, hun? Now let's analize the data and for that you just have to remember your high school days: That's a popularity contest.

 

Pick the most popular methods. They will give you a good direction of the objects that are candidates for high cohesion, and even maybe to inherit from a future super-class opening a space for a better model abstraction.

 

 
I know this is not a 100% rule but everytime I do this exercise with my colleagues we always find the light at the end of the tunnel. If you have other suggestions or if you do this analisys in a different or not usual way, please share with us.

See you later.

2 Comments

  • Thanks Edge! With your insightful techniques, just this morning, I've finished a project that I've been stuck on for months. Amazing! Thanks.

  • Nice post, very interesting -- I'll have to give this a try.

    It's generally worthwhile to attack things from different perspectives, it almost always clarifies the problems and points to better understanding and subsequently better design.

Comments have been disabled for this content.