some variant of coupling. Even simple applications need to be coupled against
standard OS or Framework functionality to achieve many tasks.
Coupling is the action of having two independent entities where; for one to
function the other must be present.
The term entity is purposfully nebulous. An application having a compile time
dependency on an external SDK is a form of coupling. So is one class inheriting
members from a base class. So is making an RPC call to some remote host to
perform an action. So is having an interface change trigger a JIT when the
system is exposed to a new assembly.
Coupling is usually contrasted with cohesion. Low coupling often correlates
with high cohesion, and vice versa. ... Low coupling is often a sign of a well
structured computer system and a good design, and when combined with high
cohesion, supports the general goals of high readability and maintainability.
There are two main families of coupling.
These are obviously compile time vs. runtime combinations.
Each family of coupling has corresponding species memebers:
With logical coupling, individual classess and components have direct
connections into the inner working of other classes or components. This style
of coupling is notorious for breaking the rules of encapsulation and eventually
bringing development to a halt. With classes relying on the internal state of
each other; you cannot predict where a change will ripple to. Fixing one bug
or adding a feature often introduces another. Most changes, even insignificant
ones, causes a total rebuild and regression test.
Type coupling is the intermediate sophistication of coupling. Rules
of encapsulation are followed and the compiler is used to detect errors.
Operations are wrapped in objects such that the compiler's static typing will
prevent mixing the wrong objects and operations. Much of the features of this
type of coupling come from properly applying OO techniques. Components should
be properly abstracted and direct in purpose. If the objects are not properly
purposed--their interactions can form the same style of rippling bugs that are
due to coupled logic.
Type coupling itself can be divided in two: Ambigious and Unambigious type
coupling. With unambiguous type coupling; one passess and accesses a class
itself. Any changes to that class will cause a ripple. Ambigious access lets
you work with the class without knowing exactly what it is. Ambigious coupling
is most commonly achieved in two ways: First, handing around a reference to a
base class [with virtual methods] instead of the final product. Second, relying
on a variant style container class that envelopes the specific class [or his base...]
These are common when using COM; with the first case being the IUnknown
interface himself. All classes must derive from him, so you can always
downcast to that least common denominator. The second being COM's VARIANT type.
A variable that will envelope most data formats himself.
Signature coupling is considered the most sophisticated form of
coupling. Methods are rarely called directly [using using a SOA, delegate
wrappers, or lamda's.] Most parameters will be passed as combinations of basic
types and enums. Testing becomes easier since if one can guarentee that
the inputs of an entire code segment are the same: the outputs will be good.
One must only test the output of the feeder code.
There are some serious issues with full signature coupling. First, is the
obvious overhead of having to repackage data and marshall calls. Even if in
the same thread, repeatedly copying strings can be time consuming. Second,
the power of full signature coupling is that you do NO binding until
runtime. Without having proper wiring diagrams and documentation, this is
The general rule with coupling: only the simplest objects should have couplings.
[Eg. Have a simple object that functions as the base class do the binding and
do little else. From that class you can derive children that make use of
the class's properties.]