Applying UML and Patterns by Craig Larman (Amazon) has an extensive overview of the nine GRASP Patterns to aid in the learning of object-oriented design principles. I have covered the following GRASP Patterns in other posts:
Applying UML and Patterns, although at its third version, has my vote for the best book of 2004!
Low Coupling
Problem: How to support low dependency, low change impact, and increased reuse?
Solution: Assign a responsibility so that coupling remains low.
Coupling is a
measure of how strongly one element is connected to, has knowledge of,
or relies on other elements. An element with low (or weak) coupling is
not dependent on too many other elements.
A class, for example, with high (or
strong) coupling relies on many other classes. Such classes may be
undesirable; some suffer from the following problems:
- Forced local changes because of changes in related classes.
- Harder to understand in isolation.
- Harder to reuse because its use requires the additional presence of the classes on which it is dependent.
As mentioned above, low coupling is
desirable because a change in one area of an application will require
less changes throughout the entire application. In the long run,
this could alleviate a lot of time, effort, and
cost associated with modifying and adding new features to an
application.
Just like cohesion, coupling not only applies between classes in an application but also between layers
in an application. Within each layer you want coupling low and
between layers you want coupling low. There is no magic to
keeping coupling low in an application. The key is to minimize
the number of dependencies from class to class and layer to layer.
In
general, if you need to assign a new responsibility to an object that
needs to be an information expert on class X, first look to assign the
responsibility to objects that are already information experts on class
X. This will keep coupling low.
Identify Unstable Areas of the Application. Keep Coupling Low.
Realistically, high coupling in of
itself isn't a bad thing in my opinion unless you have high coupling
between classes, subsystems and systems that are highly unstable.
In every application you build, you have to identify highly unstable
objects and systems. To minimize the impact of instability in the
system as a whole, you want to keep coupling low in the unstable
areas of your application.
Low Coupling Can Cause Unnecessary Complexity
If a part of your application is not
really unstable, don't treat it as such. How many times have you
heard a person boast about having a data access layer that is
loosely coupled to the rest of the application, but which there is an
unlikely chance that a different database / data access layer will be
used by the application? :) Low coupling for the sake of lowering
coupling can (but not necessarily will) cause unnecessary complexity in
your application and perhaps cause more harm than good. Pick your
battles wisely.
Law of Demeter (Don't Talk to Strangers)
The Law of Demeter places constraints
on what objects you should send messages to within a method. It
states that within a method, messages should only be sent to the
following objects:
- The this object (or self).
- A parameter of the method.
- An attribute of this.
- An element of a collection which is an attribute of this.
- An object created within the method.
The intent is to avoid coupling a client to knowledge of indirect objects and the object connections between objects.
In other words, avoid chaining within
a method because it creates a higher degree of coupling:
sale.getPayment().getAmount();
Probably more than you wanted to know about low coupling. :)