Coupling and cohesion are important software architectural concepts and, being abstractions, are often hard for many people to relate to everyday life. In the realm of software development, the proper application of these concepts is often the difference between flexible software that can change gracefully over time and that which cannot. Many outside the realm of software development mistakenly assume that coupling and cohesion have little meaning for them—they are wrong.
Any system, whether it is software, a business, or a piece of machinery, can benefit from the application of these concepts because they are basic guidelines for building flexible, adaptable systems. Previously, I wrote about coupling and cohesion from the standpoint of software design. However, others beside software engineers and programmers need to understand these concepts because of their importance. Having seen an online discussion in which one participant insisted that he wanted the EHR user interface to be tightly-coupled to the database (a very bad idea), it became obvious that more needs to be done to explain what these software design principles mean in everyday terms.
Coupling: A concrete example
Coupling is defined as the degree of interdependence between two or more classes, modules, or components. Tight coupling is bad, and loose coupling is good. When system components are highly dependent (i.e., tightly-coupled), it is difficult to change one without affecting the other. In the case of the commenter who wanted the UI tightly-coupled with the database, this would mean potentially that the contents and structure of the database would be directly tied to the user interface. Change the database and the user interface code might break. Change the UI code and the database might require restructuring—no one wants to live like that.
Car repairs and tight coupling
Enough about software, I suffered the slings and arrows of tight coupling while getting my car repaired. A few years ago the water pump on my car died. In most cars, the water pump is easily accessed, and replacement is straightforward (loosely-coupled). For some reason, the engineers who designed my car decided the water pump should be difficult to replace, so they placed the pump behind the engine. The only way to replace the pump was to remove the engine! The result? Because the engine had to be removed just to replace the water pump, a repair that in most cars costs less than $200 and takes a couple of hours at best, cost me over $700 and took three days! This is the sort of misery tight-coupling can cause.
Good system design, no matter what type of system it is, requires that one should be able to update, change, or repair key system components without having to significantly disturb (if at all) the components that are already in place. Loose coupling is good.
Cohesion: A concrete example
High-cohesion is the factor that allows loose coupling to work so well. Cohesion is defined as the degree to which all elements of a module, class, or component work together as a functional unit. High cohesion is good, and low cohesion is bad. Think of cohesion as specialization in the sense that high-cohesion components/modules do only a few things (maybe just one) and do them very well. When a component/module is specialized it serves a narrow, but specific function. That being the case, when that functionality is required, it only exists in one form or location. The opposite, low cohesion, equates with a jack-of-all-trades approach. Since high-cohesion components do one or just a few things well, when something breaks or needs to be changed or upgraded, there is only one place where that change needs to occur. In my car example, the water pump manages water, not the brakes or the lights. If the brakes stop working, there is no need check the water pump.
Cohesion: An office example
In small practices one person often handles many jobs. This works fine until either the tasks become more complex or the workload increases significantly. For example, the person who checks patients in may pull the chart and verify insurance status. Thus, one person is handling medical records, billing and intake functions. If only two or three patients show up per hour, and there is only one provider, this arrangement might work well. However, it might not scale to accommodate 30 patients per hour who have complex verification requirements.
Here is where cohesion comes into play. First, improving efficiency and productivity for each major function requires specialization. Cross-training is great until deeper expertise is required. Medical records professionals are required to deal with special circumstances such as HIPAA, state medical records rules, and subpoenas. Similarly, managing complex insurance details or straightening out payment refusals from many different insurers requires someone with an advanced skill set. Once specialization occurs, each job function can be managed separately, which allows for loose coupling.
A retail location is the perfect place to see coupling and cohesion in practice. In fast-food restaurants, cashiers take orders and payments; others assemble orders while another group cooks. Now consider a low-cohesion, tightly-coupled version where the cashier takes the order, cooks it, bags it up, and then accepts payment. This might work at 11PM when only two customers are being served, but never at lunch hour. Efficiency, productivity, specialization and ease of change/update/replacement are the benefits of low coupling and high cohesion.
Spotting low cohesion and tight coupling
Once the basic benefits of high cohesion and low coupling are understood, it is easy to spot violations of these principles. Here are a few signs that you might be dealing with coupling and cohesion problems.
- Lack of a separate configuration utility – There are very few options for changing a seemingly minor interface feature (text color, size, or window location), assuming it can be changed at all.
- Absence of a workflow engine – There is no way to change the workflow of an EHR system other than custom programming.
- Poor separation between models/components – An update to one feature breaks other features.
- One user interface for different platforms – The user interface is the same for the web and the mobile version of the products, but it only works well on one of them.
- Adding functionality requires a software upgrade—The system does not support plug-ins or other add-ons that can extend functionality as needed.
Far from being abstract principles relegated to the domain of software design, coupling and cohesion make just as much sense, and are just as useful, in everyday life. Understanding them can be very helpful when interacting with software developers, and, as I discovered, when buying cars.