Coupling between types -- A retrospective
Before we dive into a more detailed code example I just want to take a moment now to reflect, and to look at the Coupling Between Types article from the point of view of Simple Design.
Let’s recap the four rules of simple design. Code that is “simple” (ie. habitable) must satisfy the following criteria:
Passes all its tests
Expresses our intention
Says everything once and only once
Has nothing superfluous
These criteria go back to the origins of Extreme Programming, and plenty of description and discussion can be found in the C2 wiki, so I won’t repeat it here. I will simply note that I view Implicit Coupling as a violation of the Once and Only Once rule. And that making implicit coupling explicit will also usually improve the expressiveness of the code — that is, as we shall see in later examples, making coupling explicit will also tend to cause us to express our intention better.
Joe Rainsberger has written persuasively that rules 2 and 3 of Simple Design tend to work together, acting as a tight feedback loop that causes us to improve both aspects of our code simultaneously. I think we saw this in my earlier ListOfLinks
example, because both of the proffered improvements also express more about our understanding of the domain.
Going back to the C2 wiki and the origins of simple design for a moment, there is a very interesting aside in the more detailed discussion of Once and Only Once:
Methods and classes should be implemented so they can be understood totally from their public interfaces
Paraphrasing slightly, and stepping away from purely object-oriented language, that note is saying that an encapsulation unit’s dependencies should be somehow obvious from the outside — which I take to be another way of talking about the need for explicit coupling. I suspect that as these articles develop I will in fact also be saying something more: that the encapsulation unit’s relationships should all be obvious from the inside too. That is, if a change to something elsewhere in the codebase could cause this function to misbehave, that possibility should be obvious locally, within this function itself.
So I’m not saying anything new here; just finding alternative words to say what was known in the previous century.
Next time: a bigger example. Stay tuned…