ad1

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.