“High-level modules should not depend on low-level modules. Both should depend on abstractions.”
Welcome to a core principle of software architecture: Dependency Inversion, the “D” in SOLID
. In this article, we’ll explore what it means in practice, how to implement it in Go using interfaces and dependency injection, and why it’s essential for writing unit-testable code.
🧠 What Is the Dependency Inversion Principle?
The Dependency Inversion Principle (DIP) flips the traditional dependency model:
❌ Traditional: High-level business logic depends directly on low-level implementation (e.g., a database).
✅ DIP: Both layers depend on abstractions — usually in the form of interfaces.
It’s about reversing the direction of dependency to reduce coupling and improve flexibility.
💡 A Quick Example: Tightly Coupled Code
|
|
This code:
Tightly couples OrderService to a concrete *sql.DB
Is hard to test in isolation
✅ Refactor with Dependency Inversion
Let’s invert the dependency:
|
|
Now:
OrderService depends on an interface
OrderRepository can be backed by a real DB in prod or a mock in tests
🛠️ Enter Dependency Injection
We’ve inverted dependencies — now we need a way to supply them. Manual constructor injection in Go:
|
|
At runtime, inject the actual implementation:
|
|
🧪 Why This Rocks for Testing
DIP + interfaces = test-friendly code.
|
|
You’ve isolated business logic from infrastructure — the holy grail of testability.
🔄 Summary
DIP inverts traditional dependency direction: high-level modules depend on interfaces, not implementations.
Interfaces define contracts at the boundaries.
Dependency Injection supplies those interfaces at runtime.
Unit Testing becomes effortless when your logic isn’t tangled up in database, network, or file system concerns.
🧭 When to Use DIP in Go
✅ When abstracting IO, storage, APIs, or 3rd party integrations
✅ When writing business logic you want to test independently
❌ Not needed for everything — Go prefers concrete, simple code unless you need indirection
🚀 Follow me on norbix.dev for more insights on Go, system design, and engineering wisdom.