dover said:
It has be often mentioned that the coupling among objects should be
avoided.
Define coupling. All authors seem to "know it when they see it".
What're the major cases that objects are closed coupled?
I (authoritatively) define coupling as "A must change only because B
changed."
Put another way, I associate my definition with a transition. Staring at a
static instance of A and B won't tell if a given change, C, will reveal
coupling. Attempting the change will reveal it.
The other kind of association is "coherency". That essentially means "good
coupling". I define it as "A and B share legitimate reasons to change."
Write lots of unit tests. Write them before writing the tested code, and
make them fail before making the tested code pass. Then refactor, testing
every few edits, until your design contains no duplicated definitions of
behavior.
Those forces overwhelmingly crush out all possible coupling from your
design. Under such a system you honestly needn't fret about coupling; it
becomes a non-issue, like bugs.
For example:
int main()
{
Source aSource("a b\nc, d");
string
token = aSource.pullNextToken(); assert("a" == token);
token = aSource.pullNextToken(); assert("b" == token);
token = aSource.pullNextToken(); assert("c" == token);
token = aSource.pullNextToken(); assert("d" == token);
token = aSource.pullNextToken(); assert("" == token);
// EOT!
}
That's just one puny test, lacking a test rig such as CppUnit. But it
already proves a very important aspect of the class Source's coupling.
You can construct a Source object using only main() and a string argument.
You are not required to construct or deploy or call or instantiate or
register or jump-thru-hoops any other objects, just to get a useful Source
going.
The complete application that code grew into appears here:
http://www.c2.com/cgi/wiki?MsWindowsResourceLint
I would be interested to learn if anyone thought any of my classes in there
were coupled. Or incoherent.