In my previous post, I discussed how the mind is naturally limited in the number of things it can consider at once, and how we create abstractions to increase the range of our thinking. By using abstractions, we can hide the details of how something works, thereby allowing ourselves to handle more information and still only have to keep in mind a small number of discrete items. This concept is called Unit Economy.
A consequence of this limitation is that we naturally design complex systems by breaking them down into simpler pieces. If any one piece is still too complex to build, then we break that piece down even further. The act of breaking a system into pieces serves the same function in engineering that creating abstractions does in thinking. Both allow us to ignore the details how a part of the system works, and just keep in mind the overall notion of what it does.
In order for this decomposition to work, however, we must follow two principles: Coupling and Cohesion.
Coupling is the extent to which two components are interconnected. This connection can be defined in terms of actual connections in the final design. But, for our purposes, consider it in terms of how much one has to know about one component in order to understand the function of the other. The crucial point is that Coupling describes the mental load required to understand the relationship between the two components.
To take some examples in the physical world, consider a toaster and a gas stove. A toaster is loosely coupled to the rest of the kitchen. It has a single plug, which is an industry standard, and which is shared by nearly every other electrical appliance in the kitchen. On the other hand, a gas stove is tightly coupled to the rest of the kitchen. It requires a gas main, a vent to be installed above it, an exhaust pipe, and it must be mounted flush with the rest of the cabinetry. When installing a toaster, you simply have to find a flat surface near a plug. When installing a gas stove, you need to understand quite a bit about the structure of the whole kitchen. The mental effort required to understand how a toaster is connected to the rest of the kitchen is far less than that required for the stove.
Cohesion is the extent to which all the parts of a component serve a unified purpose. For the purposes of computing mental load, we measure this by how easily we can come up with a single sentence which describes the essence of what the component does, and by whether each part of the component is needed to accomplish that task. The crucial point in terms of Unit Economy is that we are able to come up with a simple abstraction for the component which allows us to ignore the details of how the component works.
For some examples of strong and weak cohesion, consider a television set and a swiss army knife. In the television set, the description of what it does is pretty simple: "A television set converts a TV signal into a visible picture". On the other hand, describing a swiss army knife isn't nearly so simple. Attempting to come up with a similar statement gets pretty awkward: "A swiss army knife is a multi-function device which provides the ability to conveniently store and reveal tools to: cut things in a variety of ways, drive screws of various kinds, etc." When considering building some kind of system with these things, it's much easier to keep in mind a simple definition (like the TV set) than a rambling, complex one (like the swiss army knife).
So, what does this have to do with programming? More on that next time.