How Loose is your Coupling?

One of the repeating themes that ZapThink frequently touts is the concept of loose coupling as one of the idées fortes or powerful tenets of Service-Oriented Architectures (SOAs). In fact, there’s so much emphasis on loose coupling that many people jump to two natural, but false conclusions: first, that because loose coupling is so good, then tight coupling must be bad, and second, that there are only two levels of coupling, namely loose and tight. Well, neither of these statements is truly accurate.

First, some definitions. Coupling is a term that describes the level of common knowledge necessary by a provider and a consumer in a distributed computing exchange. In a tightly coupled exchange, the programmer of one participant (say, the consumer, or client) must have detailed knowledge about the behavior, such as the method calls, messaging protocol, synchronous behavior, or message semantics, of the other participant (in this case, the provider, or server) in order to successfully complete the required interaction between the two pieces of software. Likewise, in a fully decoupled exchange, the two participants need have no knowledge about each other in order to interact. And finally, in a loosely coupled exchange, the two participants may have specific, but more limited knowledge about each other. Such information appears in a Service contract, which is a document external to each participant that provides the information each participant needs to interact with the other.

However, this discussion of loose coupling vs. tight coupling misses the key fact that coupling is in reality a spectrum of levels. There’s really no such thing as true tight coupling or full decoupling, but rather more or less loosely or tightly coupled in relation to some other distributed computing approach.

Service contracts: no panacea
First, it’s important to understand the relationship between Service contracts and loose coupling. Service contracts, in fact, are neither necessary nor sufficient to guarantee loose coupling. Proprietary Service contracts, for example, offer a certain measure of loose coupling, but each participant must understand and code to the specific contract format beforehand — in other words, they are still tightly coupled at the contract level. As a result, distributed computing exchanges governed by proprietary Service contracts are less loosely coupled than those governed by standards-based contracts. This limitation of proprietary contracts gave rise to Web Services, which provide a standards-based Service contract language, the Web Services Description Language (WSDL), that enables coders of each participant to build their software without having to agree with each other on the format of the contract definition language — they each simply have to follow the standard.

Nevertheless, even WSDL contracts only provide a certain measure of loose coupling, because they don’t provide all the information required by both participants. In particular, they describe the Service interface (i.e., the server participant), but not the Service consumer (that is, the client), including required information about security, service level requirements, and other metadata that might describe either participant in an exchange. Some vendors are addressing this lack by supporting Service delivery contracts that augment the WSDL contract with additional metadata about the consumer. Other vendors are hammering out follow-on specifications to the core Web Services standards that address these additional metadata issues. In either case, these additional metadata about the Service interaction enable looser coupling than WSDL contracts alone.

What about full decoupling?
So, if loose coupling is good, shouldn’t full decoupling be better? Taking a look at what “full decoupling” means in practice should shed some light on this question. A fully decoupled interaction is one where the two parties in the interaction have no advance knowledge whatsoever about the structure or content of the interaction. Some event-driven mechanisms are thought to be fully decoupled, in that one piece of software can publish an event without providing any information about that event, and subscribers to that event can then receive it and process it as they like.

However, it’s important to point out that the term “decoupled” is actually a misnomer, because even in the most decoupled event-driven architectures, recipients of events still have some information about those events. The publishers of the events often sort them into topics, which are a form of metadata. In other cases, more metadata are available about the event, including its size, format, etc. However, these metadata are often ad hoc, in the sense that they come along with the event, rather than being contained in a separate Service contract. In other words, such interactions may be uncontracted, but they are not truly decoupled. Therefore, “full decoupling” really means “more loosely coupled than contracted Services.”

The human element
It’s also possible in some circumstances for the consumer software to introspect an incoming message. Introspection means looking inside a message or an object to see what it contains and how it’s organized. Introspection, however, has its limitations as well. Typically, objects support introspection by offering an introspection interface — in other words, methods the calling program can access to query about the internal structure of an object. In the world of Services, however, interactions are via messages, not objects, and schemas provide the metadata that consumers can use to introspect XML messages. Interactions commonly referred to as decoupled, however, don’t have access to schemas; instead, Service contracts may specify such schemas for loosely coupled interactions only.

There is another form of introspection, however, that is more loosely coupled than interactions with ad hoc metadata, and that is human introspection. Let’s say, for example, that an event contains a spreadsheet fragment. In a very loosely coupled interaction, there may be no way for the consuming software to understand the contents of that fragment, but a human consumer may be able to recognize the fragment simply by looking at it and figuring out the context of the fragment. If a person sees the text “sales data,” for example, it’s a no-brainer for a human to assume the fragment contains sales data, while a piece of software might never figure that out. However, this approach requires that the human user be able to comprehend the information they see. If the information is represented in a language the human doesn’t understand, say, then communication is lost entirely.

Ad hoc metadata and tight coupling
Ad hoc metadata describe the interfaces that Service consumers and providers exhibit as well as the messages they exchange, without falling into the formal Service contracts themselves. Since Service contracts are not sufficient for guaranteeing loose coupling, is it possible to have an SOA without Service contracts at all? The answer depends on what qualifies as a Service contract. Service contracts and other associated metadata lay the groundwork for enterprise SOAs that involve many users and complex, heterogeneous application infrastructure, but many of today’s SOAs are not that involved. In many cases, Service interfaces aren’t available to a broad range of consumers, either because the SOA provides for limited functionality, or because sufficient security arrangements are not yet in place. As long as there are certain binding-related metadata available, including how to find the Service and what protocols it supports, then some measure of tight coupling at the data or semantic level is perfectly acceptable, since the same team likely controls the consumers and providers of the Services.

Now, by “some measure of tight coupling,” we’re not saying that we have the tight coupling exhibited by remote object invocation like that provided, say, by Java RMI or .NET Remoting. Instead, we’re still Service-oriented, in the sense that all interactions are via Service interfaces that exchange messages, and we still have contracted binding information. However, we may describe those interfaces with ad hoc metadata instead of (or in addition to) Service contracts, and there has to be some agreement beforehand on the format and context of those metadata.

Such an arrangement can work quite well in a lightweight event-oriented environment, where ad hoc metadata describe published events that consumers can subscribe to. Such an approach would be more tightly coupled if consumers and providers must agree on the format and context of those metadata. However, if the content of those events are intended only for human consumption, then this event-oriented approach could be considered to be more loosely coupled. In either case, however, both approaches still fall under the broader umbrella of Service orientation. The bottom line is that each approach solves a different set of problems. How loosely coupled an interaction should be is simply a question of the right tool for the job.