Software Architecture Solution Architecture / May 5, 2023 / 4 mins read / By Mohamed Bamoh

Modularity in Software Architecture: Cohesion, Coupling, and Seams

Speed doesn’t disappear. It leaks.

Early in a project, everything feels fast.

Then the system grows. And “small changes” start taking weeks.

That slowdown is rarely caused by code volume. It’s caused by entanglement.

Modularity is how you fight entanglement.

Not as a buzzword. As a practical goal:

Change one thing without paying for unrelated things.

Modularity is not “many components”

You can have dozens of components and still have a single system-shaped knot.

Modularity is not the number of boxes. It is the quality of the boundaries.

A modular system has two properties:

  • it is easy to change one part
  • it is hard to accidentally affect other parts

That second point matters more than most people think.

Cohesion: keep what changes together

Cohesion is simple to say and hard to do:

Put responsibilities together if they change for the same reasons.

When cohesion is high:

  • features are easier to implement
  • bugs are easier to localize
  • teams can own a slice without owning the world

When cohesion is low:

  • logic is scattered
  • changes require scavenger hunts
  • every feature becomes a cross-cutting project

A good sign of cohesion is boring commits. A change touches one area, and the diff looks obvious.

Coupling: stop change from spreading

Coupling is how change travels.

Low coupling doesn’t mean “no dependencies.” It means dependencies don’t dictate your pace.

There are a few coupling types that create slow systems: 1) Data coupling Two parts depend on the same tables or internal data structures. One change forces the other to change.

2) Runtime coupling A request must hop through many parts to succeed. Failure and latency spread like fire.

3) Build-time coupling Shared code and shared release trains. A small update becomes a coordinated event.

4) Temporal coupling Two teams must deploy in sync to make anything work. You don’t have autonomy. You have choreography.

If you want to stay fast, you reduce these first.

Seams: design points where change can happen safely

A seam is a deliberate “swap point.”

It’s where you can replace an implementation without rewriting the whole system.

Examples of seams:

  • an interface between domain logic and infrastructure
  • an API boundary between modules
  • a message contract between producers and consumers
  • a plugin-style abstraction around external vendors

Seams matter because architecture changes rarely happen cleanly. They happen mid-flight.

A system with seams can evolve without panic.

Boundaries must be real in code, not just in slides

This is where modularity usually fails.

People agree on boundaries, then implement them softly:

  • anyone can import anything
  • anything can query any table
  • “we’ll refactor later”
  • “just this once”

That’s how boundaries die.

A boundary becomes real when you can enforce it:

  • dependency rules (what can talk to what)
  • ownership rules for data
  • stable contracts for integration
  • tests that fail when the boundary is violated

This is not rigidity. It’s what makes freedom possible later.

The smell test: can you change this without a meeting?

Here’s a practical way to assess modularity: Pick a likely future change:

  • a new pricing rule
  • a new authentication provider
  • splitting one workflow step
  • changing how a report is calculated

Now ask:

  • How many parts must change?
  • How many teams must coordinate?
  • How many deployments are required?
  • How many consumers might break?

If the answer is “a lot,” you don’t have modularity. You have a shared fate system.

Modularity is the foundation for everything else

People talk about “scaling architecture.”

The truth is simpler: You can’t scale a system that can’t change safely.

Modularity is what makes:

  • independent delivery possible
  • reliability easier to engineer
  • microservices a choice instead of a rescue attempt
  • event-driven integration a tool instead of a mess

If you invest in one structural property early, invest in this.


Key takeaways / refresher bullets

  • Modularity means change stays local and accidents don’t spread.
  • Cohesion: group responsibilities that change for the same reasons.
  • Coupling: reduce data, runtime, build-time, and temporal coupling.
  • Seams are deliberate swap points that let you evolve without rewrites.
  • Boundaries must be enforceable in code, not “agreed in meetings.”
  • Smell test: if a simple change needs a meeting, modularity is weak.
  • Modularity is the foundation for autonomy, operability, and safe evolution.