About coupling and cohesion

cohesioncoupling

At the end of this discussion about coupling and cohesion https://www.youtube.com/watch?v=hd0v72pD1MI some renowned programmers agreed in the general thought that to achieve high cohesion you have to join things, and to achieve low coupling you have to split them.

This seems to be a common thought but I think is totally the opposite.
In my opinion the most cohesive module is the one that doesn't exist or have just one small feature, and in the other hand the less coupled module is the one that only depends on itself

In a small example, the following module:

(feature A, feature B, feature C)

has low cohesion and low coupling (no coupling at all).

Trying to achieve high cohesion I will try to split that module:

(feature A)-(feature B)-(feature C)

now I have three high cohesive modules but now the system could become highly coupled.

I see this issue in the Microservices world, where splitting things seems to be equal to "decoupling" your system.
Then you have to touch 4 different services and 3 layers in each one to add a simple property, but no one seems to care about that.

I would like to hear your thoughts about this

Best Answer

I see this issue in the Microservices world, where splitting things seems to be equal to "decoupling" your system. Then you have to touch 4 different services and 3 layers in each one to add a simple property, but no one seems to care about that.

Excellent insight!

This is not just microservices, as you say. Even in monoliths a layered architecture results in you modifying all "layers" most of the time, even for simple things.

"No one seems to care" is also a great insight. Although, I think it has more to do with a lot of bad, and no good examples being widely available.

If you care about maintainability, i.e. if you want to have (business-relevant) changes mostly localized (such as adding a simple property somewhere), you'll find that you need to do things differently to what most projects do.

In short, and this has been years worth of learning (/ unlearning) for me, you'll have to make sure that objects don't publish their data. Having a "getter" in an object basically means that data is used elsewhere, i.e. this object will probably change if any of the usage sites want something differently. This is what cohesion is supposed to prevent. You'll have to include all functionality in the object that is cohesive, including presentation, persistence, etc.

Coming back to your example about adding a property. You can imagine the only way you will have a single place of modification, if you include both UI, "logic" and persistence in the same object. Ironically this is what object-orientation was supposed to do, include function with data.

Regarding microservices, those can be done this way too. If your microservices are not CRUD-based (as most are), but implement a closed, self-contained function, including UI, you will not have this problem of modifying many on a single change.

As you probably realize, all this is dogmatically opposed by most current design / architectural patterns, which always try to split on technical merits. Like always splitting everything UI from everything that is "pure" calculation.

So this is where we're at. You seem to be asking the right questions, so keep asking, don't take anything on authority!

HTH