Thursday, 6 October 2011

Defining loose coupling

In order to achieve a successful SOA, most architects know that loose coupling is essential.  Too bad, then, that most people can't actually define what it is, why you need it, or when you need it.  So, I'm going to take a crack at clearing up the mystery.
Many sources (for example, Loosely Coupled, W3C, and WikiPedia) essentially define loose coupling as "platform agnostic".  By this definition, the more different platforms and environments that can talk together, the more loosely coupled you are.  If you were to take this as the definition, what you'd find is that "legacy" middlewares such as CORBA and DCE would be considered as good (if not better) for loose coupling than web services.
So, wouldn't it make sense to base an SOA on, for example, CORBA?  Absolutely not - and I'm not saying this just because I'm a web services bigot (I was on the CORBA standards committees, so I'm keenly aware of the technology advantages and limitations).
There's a key element to loose coupling that's ignored by all of these definitions: versionability.  If you can't version consumers, providers, and cross-cutting policies independent of each other, you don't have loose coupling, and you won't have a scaleable SOA.  Why?  The owners of consumers, providers, and policies rarely operate on the same budgets, timeframes, or schedules.  You fundamentally can't change this reality so, SOA must be able to embrace it.
So, I would define loose coupling as "the state in which the impact of change (change in consumers, providers, or cross-cutting policies) is minimized across dependencies."
Given this, there are a lot of reasons why legacy middlewares (whether CORBA, RMI, EJB, or .NET remoting) can't easily provide loose coupling.  While I'm not going to go into details, among the reasons are the inability to unilaterally extend the message schema without impacting dependencies, and the inability to interpose intermediaries for purposes such as zero downtime version rollover.  Because of the limitations of legacy middlewares, versioning typically ends up meaning "never change the interface" (create a separate interface for subsequent versions - which experience proves is both error prone and exceedingly time consuming) or risk breaking dependencies.
Given this definition (with any luck, you might even agree with me!), it's pretty easy to define when you need it.  If A depends on B (or vice versa), you need loose coupling only when A may version independently from B.  That is, if A and B are versioned together, loose coupling between them is unnecessary.  For lack of a better option, I use the term "unit of deployment" (a grouping of "things" which essentially deploy together):  loose coupling is important across units of deployment, whereas tight coupling is fine within a unit of deployment.
So, within a unit of deployment (regardless how many tiers this encompasses), it's perfectly reasonable, and in fact often preferable, to use protocols such as EJB, RMI, or .NET remoting.  But, when you're going across units of deployment, you should try to use web services, because you will be more easily able to achieve loose coupling.

No comments:

Post a Comment