Blog
About

© 2026 Uzair Tariq

← Back to blog

Orthogonality in Practice

May 30, 2026The Pragmatic ProgrammerSoftware Design

Orthogonal components don't affect each other. Change one, and nothing else needs to move.

That sounds abstract until you notice it has a direct metric: how many files does a typical one-line behavior change touch?

The diff test

Add a field to a form. Count the files.

  • 2-3 files: healthy. The change lives where the concept lives.
  • 8+ files: the concept is smeared across the system. A form field shouldn't require edits to a validator registry, a DTO, a mapper, a migration, a serializer, a fixture, and three tests that assert shape rather than behavior.

The second case isn't caused by bad code. Every one of those files is reasonable in isolation. It's caused by a layering scheme where one idea has to be re-declared at every level.

Where non-orthogonality hides

Shared mutable config. A settings object every module reads means changing a default silently changes six behaviors.

Inheritance used for reuse. A base class with eight subclasses is eight things you might break by editing one method.

Cross-module test fixtures. One shared testUser fixture, and adding a required field breaks 40 unrelated tests. The tests are now coupled to each other rather than to the code.

The cheap fix

Most of the recovery is boring: pass dependencies in rather than reaching for them, prefer composition, and give each test its own data.

The payoff isn't elegance. It's that the blast radius of a mistake stays small enough to reason about, which is the only thing that makes a large codebase survivable.

Previous

← Tracer Bullets Beat Prototypes