Loose-Coupling — and Semantic Mismatch
In todays episode of “Lets Talk About Stuff You Already Know” we cover Loose-Coupling. The baseline definition is kinda obvious — it’s a system is which each component has limited knowledge (and use!) of the other components.
That said, if that was the extent of it, I would just have linked to the Wiki page, and have been done with it. The thing is, semantics are important, and what the term means to me is not necessarily what it means to somebody else. Given that the most costly software issues tend to be the ones made earliest, it behooves you to limit misunderstandings in the Design stage!
Consider a simplified take on the development cycle, viz. Design → Develop → Test → Deploy. With a loosely-couple system, you can
- • Design your component with limited involvement from other components. Whats more, you can update this design without other folks having to change their stuff.
- • Develop your component without much co-ordination with others, e.g., very few instances of “Uh, s**t, we need to update our version of
libgen
”. - • Test your components without a omnipresent need for an integrated test environment across everything.
- • Deploy your components on demand, without having to worry too much about the state/status of other components, products, and services.
So far so good, right? That said, did you notice the weasel-words in the above points? Like “limited involvement”, “without much co-ordination”, etc.? They are there for a reason, and that is because we are talking about Loosely-Coupled systems, and NOT Decoupled systems!
This is the heart of the matter — that Loosely-Coupled systems exist somewhere on the continuum between Tightly-Coupled , and Decoupled systems. As a result, when building Loosely-Coupled systems, you frequently find the following
- • Over-Engineering, as the different teams actually build Decoupled systems, resulting in duplication, waste, and whatnot. e.g., One component is built in golang/manual-installs, another in nodejs/docker-swarm, and another in ruby/k8s (true story). Each team now has it’s own infrastructure headaches, cross-team migration is minimized, hiring is a PITA, etc.
- • Semantic Mismatch, where the different teams have their own assumptions about where on the above spectrum they lie. e.g, a team that assumed that they could use the postgres instance that was being provisioned/maintained by a different part of the system — which was fine and dandy till the other team migrated to Cassandra…
The bottom line here is that, as you build out your system, be sure to document — and share! — the design assumptions behind the architecture across all the teams. Whats more, on a fairly regular basis, reassess these assumptions, and see if anything needs to be added, updated, or removed. And always remember, the focus here is on sharing the knowledge, not on keeping the assumptions static!
Comments