June 15, 2004
Loose coupling has more up front costs than tight coupling. The assumption
is, over the life of a component (or service) that the loose-coupling device
will pay for itself.
A common belief is that software engineers should design services to be 'loosely
coupled'. That is, they should verify that the service can speak the 'least
common denominator' and do it in a manner that mitigates the impact of location:
attempt to minimize the impacts associated with distributed computing (location
transparency).
In the physical world, we use devices to decouple entities. Instead of soldering
two components together, we connect each component to a plug and then use the
plugs to connect the items together. This is necessary in the physical world.
In the logical world, we have the opportunity to attach a 'plug' to the end of a
component or a service. And just like in the physical world, it costs more money
to buy and attach the plug. But, the plug should make the component more
reusable. That is the investment.
Imagine an electrical component that is attached to a printed circuit board. The
component has nice plastic plug coming off of it enabling other components to
easily connect to it. In addition, the wire lead on the component is exposed and
it is mounted in such a way that additional wires can be soldered directly to
it. In essence, the component was designed with loose coupling in mind (the
plug) but the instantiation (or the use) of the component allowed the engineer
to bypass the plug by directly connecting to the wire lead.
Here, the component has both 'component design-time' and 'assembly design-time'
properties. The 'component design-time' properties describe the features that
the component has; in our case, we are interested in the plug at the end. The
'assembly design-time' deals with the decisions that the engineer makes at
design time when they assemble multiple components together (e.g., does the
engineer use the plug or solder directly to the wire?)
When we discuss loose coupling or tight coupling, we must remember that there
are different issues to consider:
- The level of investment that was placed on enabling a component to be loosely
coupled (e.g., it comes with a plug attached). [POTENTIAL COUPLING]
- The decisions that the component assembler made when combining the piece
components (e.g., they used the plugs everywhere vs. soldered them together
everywhere vs. some combination) [ASSEMBLY COUPLING]
- The option of delaying the assembly interface mechanism decisions to runtime.
[DYNAMIC COUPLING]
A significant amount of literature is available on making components/services
reusable (creating high potential decoupled devices); thus I won't revisit. Less
is written on Assembly Coupling, but I'm still happy with my, "Service
Coupling Index" as a foundation. However, very little information is
available on the concept of Dynamic Coupling.
In many ways, Dynamic Coupling contradicts the 'loosely coupled' manifest.
Rather than stating that something must be implemented in a
certain way (asynchronous, document centric, XML based, etc.), it states that
the component need only have Decoupling Potential AND that the
component be aware of any Dynamic Decoupling Device.
I like to think of the Dynamic Decoupling Device as a "magic printed
circuit board". Here, the assembler inserts components into the board. But
rather than soldering the components together or using plugs to connect them,
the assembler will never execute the actual assembly mechanism. Instead, the
assembler tells the printed circuit board which components need to be connected
to each other. The "magic printed circuit board" is now responsible
for querying the components and determining the best mechanism to connect the
piece parts together. We have moved from explicitly stating the connection
mechanism to only stating the intent.
In the physical world, creating the "magical printed circuit board"
is... well, challenging. In the logical world it is quite easy. At the core, it
means:
- We use policies to describe capabilities and interfaces.
- We publish the policies in a consistent manner.
- We perform protocol negotiation at runtime.
- We build components with high decoupling potential.
- We build components that were designed to connect to Dynamic Decoupling
Devices.
- We quit hardcoding our assembly mechanisms.
- We mandate the use of Dynamic Decoupling in assembly.
If an architecture is indeed defined by the constraints rather than the
features, than the aforementioned may serve as an architectural style that
facilitates reuse without giving up performance.
About the author
Jeff Schneider
jschneider@momentumsoftware.com
Blog: http://www.Schneider.blogspot.com
Jeff founded Momentum Software in 1997 and serves as its CEO and Chairman. Prior to founding Momentum, Jeff managed the Java consulting practice for Delphi Consultants and managed client engagements for Motorola, Sabre, and Ford. Jeff started his career at 3M where he managed the I.T. manufacturing systems group for five divisions. In 1996, Jeff wrote the first book on Enterprise Java and continues to write for leading technology publications and is a frequent speaker related to emerging technologies.
|