Every dependency is bound at some moment — when a name resolves to a concrete implementation, or a placeholder resolves to a value. Bind it in source and the choice is fixed at compile time: changing it means editing, rebuilding, and redeploying. Defer the binding and that moment moves later — to configuration, startup, or runtime — where the same change costs far less.
Deferring a binding is coupling reduction across time. The caller stops depending on a specific choice and depends only on the point where the choice gets resolved.
How It Works
- Bind at the latest stage that fits, along a spectrum: build (select a component or library) → deploy/install (config files, environment variables) → startup (resource files, init parameters) → runtime (polymorphism, plugins, service discovery, or a broker that resolves the target).
- Depend on an abstraction — an interface, a config key, a lookup — never on the concrete choice directly.
- Keep one binding point per varying choice, so the decision has a single, discoverable home.
Failure Modes
- A required variable or config key is missing or mistyped; the system fails at startup or first use, where a compile-time binding would have failed the build.
- The concrete binding is absent from source, so a fault trace must reconstruct which implementation or value was actually resolved.
- Binding points multiply until configuration becomes its own undocumented program.
Configuration is programming continued using methods unsuitable for that purpose.
— Phillip Ghadir (personal communication)
Verification
- Startup validation rejects missing or malformed configuration with a clear message, before the system serves traffic.
- The same artifact runs across environments with only its late-bound inputs changed — no rebuild.
- Swapping an implementation at a binding point — a plugin, a config value — changes behaviour with no edit to callers.
Variants and Related Tactics
- Dependency Inversion Principle: caller and implementation both depend on an abstraction the caller owns — the design-time sibling that creates the binding point defer binding resolves later.
- Reduce Coupling is the general lever; defer binding is its across-time form.
- Feature toggles, externalized configuration, and plugin architectures are concrete realisations.
References
- Software Architecture in Practice, 4th ed. — Bass, Clements & Kazman (full citation) — the Defer Binding tactics
- Clean Architecture — Robert C. Martin (full citation) — the Dependency Inversion Principle
- Balancing Coupling in Software Design — Vlad Khononov (Addison-Wesley, 2024)