Back to Home

Temporal Coupling

Identify files that often change together in the same commit

Temporal Coupling

Many years ago, I had to develop software using a custom framework designed to force all developers to adhere to so-called "best practices" around clean code and separation of concerns. This was back in the .NET 2.0 era, when concepts such as vertical slice architecture were not yet common. The framework was essentially an extended version of the classic three-layer architecture. However, instead of three layers, it introduced six layers. We had data transfer objects, business objects, a data access layer, a service layer, database stored procedures, and the UI layer.

I guess you can imagine the result. Making even the smallest change was extremely painful. For example, adding a single property to an entity required modifying at least five different files across five different projects. And we didn't write unit tests. We believed that abstraction should be sufficient to ensure code quality.

After some time, the software architects realized that this approach was fundamentally flawed, and we ended up abandoning the framework entirely. Our codebase was a notorious example of extreme temporal coupling.

Why it matters

As you can imagine, extreme temporal coupling, like in the previous example, causes huge development overhead and frustration.

Temporal coupling can also reveal hidden dependencies that your code structure doesn't show. Maybe your authentication module and payment module keep changing together. It signals a design smell. Or maybe a UI component and a database layer change together. That can indicate poor separation of concerns.

These patterns expose tight coupling between parts of your system that should be independent. When you change one thing and have to change five other things, your architecture is fighting you.

Finding temporal coupling helps you spot these problems and plan better refactoring to break apart tangled code.

Cosmic Analogy

Imagine a binary star system where two stars are locked in a gravitational dance. When one moves, the other must move in response. They are inextricably linked, their fates bound together. Similarly, files that always change together are gravitationally bound. It means you cannot touch one without affecting the other.

Cosmic analogy

Temporal Coupling Visualization

How to Fix

Analyze & Identify

  • Identify strongly coupled file pairs and evaluate if they should be merged or their dependencies removed.
  • Monitor temporal coupling metrics after refactoring to validate that architectural changes reduced dependencies.

Architectural Patterns

  • Use vertical slicing to group related code by feature rather than by technical layer.
  • Consider domain-driven design to align code boundaries with actual business concepts and reduce coupling.
  • Use event-driven architecture or messaging patterns to decouple components that shouldn't be tightly bound.

Reduce Complexity

  • Break apart over-layered architectures where simple changes require touching many files across layers.
  • Review and eliminate unnecessary abstraction layers that force changes to propagate through multiple files.

Design Principles

  • Extract shared abstractions when multiple files change together due to duplicated logic.
  • Introduce stable interfaces between modules to reduce ripple effects from internal changes.
  • Apply the Single Responsibility Principle to reduce the need for coordinated multi-file changes.
    But don't follow Single Responsibility Principle blindly
    . It can be a tricky
  • Take a look at connascence.io for more patterns and anti-patterns around code coupling.