# Understanding Architectural Coupling

# Types of Coupling

Coupling comes in many variations and can sneak into a system if care is not taken. Within Software Engineering we can generally say that coupling is -

> the degree of interdependence between software modules; a measure of how closely connected two routines or modules are \[1\]

To break things down in more detail we have -

***Data Type Coupling***

1. **Content Coupling** - Directly accessing and changing the data in another module
    
2. **Common Coupling** - Two modules sharing a global data structure
    
3. **Data Coupling** - A module passing data into another module through parameters or global data
    

***Functional Type Coupling***

1. **Control Coupling** - A module controlling the flow of execution in another module
    
2. **Stamp/Temporal Coupling** - Depending on the order of execution of other modules
    
3. **Functional Coupling** - A module's output becomes another module's input
    

***Platform Type Coupling***

1. **Message Coupling** - Communicating through a shared message-passing interface
    
2. **Interop Coupling** - Modules are dependent directly on a single platform's technology or protocols
    

---

But what does this look like as we take our level of abstraction higher?

# Coupling Boundary

As we look at *Distributed Software Systems* we need a higher level of abstraction to examine the coupling between elements. This abstraction is known as the ***Architectural Quantum***. An *Architectural Quantum* is defined from one perspective as an *"independently deployable artifact, with high cohesion, high static coupling and synchronous dynamic coupling"* \[2\]

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1676757198188/61b44d97-ce35-460c-b374-ed3217e11788.png align="center")

The relationship to coupling is clear and we can define a *Quantum* as a bounded system exhibiting, *high static coupling* and *synchronous dynamic coupling.* These forms of coupling force the bounded system to be deployed as a unit that may eschew high cohesion.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1676757206313/9dddd316-04d5-4fc3-9fbc-10ac188bcb22.png align="center")

Coupling, therefore, can cross even well-defined domain boundaries of microservices. Boundary crossing is what causes friction between teams and complex release strategies. Recognizing the underlying *Quantum* will enable us to eliminate unnecessary dependencies.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1676757218330/bf0f58b1-7e2f-43a4-a63c-11e92d159de6.png align="center")

# The Razor - *Knowledge Discipline*

Architecting a complex software system, specifically applying *Continuous Architecture*, is all about managing volatility and maximizing the *Quality Attributes* of the system. Minimizing and analyzing coupling comes down to **Knowledge Discipline***.*

> **Knowledge Discipline** - Knowledge, being both data & behavior, creates *Architectural Quantum* boundaries defined by singular ownership.

Singular ownership of *Knowledge* means that only one *Quantum* can be the source of truth for a domain's behavior or data. Let's look at a tightly coupled eCommerce example.

# Knowledge Discipline - *In Action*

We'll look at the order placement system of, my favorite, Widgets Inc. Below it's clear the *Order Service* should not be orchestrating the downstream processes.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1676759402159/51341b75-ea97-4137-8b4c-14e668390b26.png align="center")

The *Order Service* has knowledge of the *Inventory Domain/Service*, also, it's aware of the *Notification Service*. Even worse, the *Inventory Service* is "validating" the Order for the *Order Service* based on its known inventory.

Due to the extraordinarily tight coupling among all three services, this system becomes a *Distributed Monolith.* Regardless of service breakdown, the tight coupling forms a single *Quantum* that must be deployed as a unit. Changes in one system ripple through others. If the individual services cannot be independently deployed, they're not "microservices" anymore. ***The monolith is simply further apart.***

**What a mess huh?** Let's apply some *Discipline* between domains 🤓

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1676759419417/a8d2029e-d48f-402a-aa72-60ed25f80023.png align="center")

Here, both the *Order & Inventory Services* listen for an Order Placed event. Independant of one another they execute their *Domain Responsibility*. The *Order Service* records the Order and the *Inventory Service* updates the Inventory. Neither knows anything about the other. The *Notification Service* recognizes the two resultant downstream events: Order Recorded & Inventory Updated. Independently of any source of these events, the *Notification Service* executes its responsibility.

We have, however, traded the ***Data & Control Coupling*** for ***Platform Coupling*** in the form of a *Message Broker*. This is a tradeoff we can live with and the reason why comes down to **volatility.**

The *Message Broker* we've introduced offers a distinct and high 9s SLA. Also, as infrastructure, it's subject to very little change. New and evolving Business Requirements have none to little effect on the *Broker.* This provides us the tradeoff of depending on a *Message Broker* and in return, our domains become independent from one another.

# Wrapping Up

Applying ***Knowledge Discipline*** gives us a technique to determine if there's an undesired coupling between modules. By identifying *knowledge* that has multiple owners we can identify hot spots of coupling. Slicing our system in terms of *knowledge ownership* keeps bounded data & behavior independently deployable and executable.

---

\[1\] Wikipedia contributors. (2022, May 6). *Coupling (computer programming)*. Wikipedia. [https://en.wikipedia.org/wiki/Coupling\_(computer\_programming)](https://en.wikipedia.org/wiki/Coupling_(computer_programming))

\[2\] N. Ford, M. Richards, P. Sadalage, Z. Dehghani, *Software Architecture: The Hard Parts*. Sebastopol, CA: O'Reilly, 2022
