Minimizing Coupling Between Modules
What's wrong with having modules that know about each other? Nothing in principle—we don't need to be as paranoid as spies or dissidents. However, you do need to be careful about how many other modules you interact with and, more importantly, how you came to interact with them. Suppose you are remodeling your house, or building a house from scratch. A typical arrangement involves a "general contractor." You hire the contractor to get the work done, but the contractor may or may not do the construction personally; the work may be offered to various subcontractors. But as the client, you are not involved in dealing with the subcontractors directly—the general contractor assumes that set of headaches on your behalf.
We'd like to follow this same model in software. When we ask an object for a particular service, we'd like the service to be performed on our behalf. We do not want the object to give us a third-party object that we have to deal with to get the required service.
Traversing relationships between objects directly can quickly lead to a combinatorial explosion of dependency relationships. You can see symptoms of this phenomenon in a number of ways:
- Large C or C++ projects where the command to link a unit test is longer than the test program itself.
- "Simple" changes to one module that propagate through unrelated modules in the system.
- Developers who are afraid to change code because they aren't sure what might be affected.
Systems with many unnecessary dependencies are very hard (and expensive) to maintain, and tend to be highly unstable. In order to keep the dependencies to a minimum, we'll use the Law of Demeter to design our methods and functions. The Law of Demeter for functions attempts to minimize coupling between modules in any given program. It tries to prevent you from reaching into an object to gain access to a third object's methods.