Tuesday, June 23, 2009

On Software Engineering: coupling and cohesion, meaningless academic abstractions

In computer science and software engineering, the concepts of coupling and cohesion are meaningless academic abstractions that only serve to increase the cost of software engineering and decrease both performance and simplicity. In these times of rapid churn in terms of technologies and tools used to implement large software systems, the goals of maintainability and readability touted by proponents of so called loose coupling and high cohesion should come far behind goals involving performance and time to develop, when any given implementation may be outdated before it is even fully completed.

Furthermore, coupling as a concept taken outside of its goals does not stand to simple facts related to the nature of communications between two software modules. At the very least, in order for two modules to work together, they must share a common language, an agreed upon format for the data that they communicate to each other. They are at a minimum coupled to a common format or interface. It does not really matter what means are used to define that shared interface in measuring the degree to which the two modules are coupled. If that interface is changed then one or both modules using the interface will have to change. If the content or meaning of the data is changed and neither side needs to change then that part of the interface that changed must be superfluous whether the interface is defined in XML or a binary format or in terms of some programming language’s object, it does not matter.

Further still, cohesion as a concept does not deliver in terms of performance or any other meaningful measure of software engineering quality related to real world issues and not academic contrivances of what is pure and well formed. The more cohesion that modules exhibit in a system, the more communications will be required to connect those modularized chunks together so that the system can accomplish its requirements. For example, it may seems like well structured design to have all points in a system access some resource through a common module that implements such actions in one location but this requires two extra communication hops for every access executed against said resource, one to the common module then one from that common module to the resource, then two more coming back out to the calling module. Why not let every module that needs to access the resource do so in its own code inline maybe through some shared abstract interface since maintainability is almost a moot point in the face of modern IDEs that offer all sorts of refactoring utilities.

Going to extremes just to achieve high cohesion and loose coupling is a waste of time and resources and often results in reduced performance and increased complexity.


Pattern-chaser said...

Wait until you've spent a significant amount of time fixing or enhancing someone else's code, cycle after cycle. If you reach the point of 'code rot', where the code can no longer safely be changed, because of the unexpected side-effects, then you haven't been doing your job right. The concepts of coupling and cohesion address this.

Alternatively, keep moving employers so that they never find out how much you don't know, and can't deliver.

Conceptualizer said...

I have. I have also spent a lot of time on very large projects where the myth of SOAs have led to all manner of "loose coupling" that drive up cost and slow down performance with no gain in overall quality. I have seen "strong cohesion" that requires 10 times as long to run because things are so modularized that a simple call for data to a database must pass through 6 layers of packaging through 3 tiers and maybe 4 servers.
Also part of the point I was trying to convey is that all systems that communicate must be coupled at least thru a common data format and that measuring the degree of coupling is pointless.
The other part of my point was that cohesion can pass a point where you get diminishing returns as strength rises to a point where you actually start to hurt quality not improve it.
On moving employers, my rule is to always stay with a project at least until it reaches into maintenance stage, roughly 3 to 4 years for large projects. When I say large I mean projects that employee 100s of developers.

Pattern-chaser said...

The misapplication of any good coding practice is far too common, sadly. But that doesn't necessarily mean the coding practices are wrong.