Coupling

“Let’s decouple everything!” — Software engineers, anywhere, anytime

The term “coupling” has long been synonymous with bad design. But is it necessarily that evil?

According to the dictionary, “coupling” is a device for connecting parts of machinery or simply a pairing of two items. If a system is a set of components interacting to achieve a goal, then coupling is what connects these components, making it possible to achieve those goals. Coupling is what makes the value of a system greater than the sum of its parts.

Of course, there are different ways to connect system components. Some lead to modularity, while others create complexity. How do we differentiate between the two? By treating coupling not as a nuisance but as a design tool.

Design Tool

ComponentComponentComponentComponent

When designing a system, we often focus on the boxes—the components of the system. While defining component boundaries is important, the real action happens in the lines connecting them. The design of cross-component interactions can make a system complex, for example, if a change in one component necessitates changes in others. Conversely, integrations that tolerate component changes increase modularity of the system.

To truly manage coupling, we must move beyond the simplistic mantra of ‘decouple everything!’ and instead understand its impact. It manifests in three dimensions.

Multi-Dimensional Coupling

Component AComponent BDistanceKnowledgeVolatility

The figure above illustrates two coupled components. It doesn’t specify what they are—functions, objects, packages, services, or entire systems—because that doesn’t matter. What matters is the line connecting them. This line can be seen as a pipe through which components exchange data—such as instructions for operations or information from the system’s business domain. But data isn’t the most important thing exchanged between coupled components.

Knowledge

Integration requires components to exchange knowledge about each other. This can include knowledge of a component’s functionality, public interfaces, or even implementation details. The more knowledge is shared, the higher the likelihood of cascading changes—a modification in one component requiring corresponding changes in another. The extent of shared knowledge can be evaluated using the integration strength model.

Distance

The physical and logical distance between coupled components affects the cost of changing them together. Greater distance—for example, when components reside in separate services—results in higher change costs. Conversely, when interdependent components are close together, the cost of change is low—almost like modifying a single component.

While the source code structure influences distance, this dimension is socio-technical and affected by additional factors.

Volatility

The rate at which components change affects how coupling should be designed. Highly volatile components require more careful and flexible integration strategies.

But how can one predict a component’s volatility? While predicting the future is impossible, there are models useful for evaluating volatility.

Modularity or Complexity?

Once the dimensions of coupling have been identified and evaluated, how do we ensure the design leads to modularity rather than complexity? The key is to balance the dimensions of coupling.


Learn More