← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Dependency Inversion Principle (DIP)

php PHP 5.0+ Intermediate
debt(d5/e5/b7/t5)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches' (d5). PHPStan and Psalm (listed in detection_hints.tools) can detect when domain classes import concrete infrastructure classes, but this requires custom rules or strict layer enforcement configurations. The detection is not automated by default and requires deliberate setup of architectural boundary rules.

e5 Effort Remediation debt — work required to fix once spotted

Closest to 'touches multiple files / significant refactor' (e5). The quick_fix describes flipping dependencies by defining interfaces in domain layers and implementing in infrastructure — this inherently spans multiple files (interface definition, concrete implementation, and all consuming classes). Not architectural rework, but more than a parameterized fix.

b7 Burden Structural debt — long-term weight of choosing wrong

Closest to 'strong gravitational pull' (b7). DIP applies across all PHP contexts (web, cli, queue-worker) and is tagged as a SOLID principle affecting OOP architecture. Once DIP is either followed or violated as a pattern, every future class design is shaped by this choice. Violations accumulate as coupling debt; adherence requires consistent discipline across the codebase.

t5 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'notable trap' (t5). The misconception explicitly states that developers confuse DIP (the principle) with DI (the technique). This is a documented gotcha that most developers eventually learn, but initially causes design confusion — thinking that using a DI container automatically satisfies DIP, when the abstraction direction matters independently.

About DEBT scoring →

Also Known As

DIP Dependency Inversion Principle depend on abstractions

TL;DR

High-level modules should not depend on low-level modules — both should depend on abstractions (interfaces), not on concrete implementations.

Explanation

DIP (the D in SOLID) inverts the conventional dependency direction. Instead of OrderService depending directly on MySQLOrderRepository, both depend on OrderRepositoryInterface. This decouples business logic from infrastructure — the repository can be swapped for an in-memory test double or a different database without changing the service. In PHP, DIP is implemented by type-hinting interfaces in constructors and wiring concrete implementations in a DI container. Violating DIP produces tightly-coupled code where changing a storage driver requires editing business logic.

Common Misconception

Dependency inversion and dependency injection are the same thing. DIP is a design principle (depend on abstractions, not concretions). DI is a technique for achieving it by passing dependencies in. DI implements DIP but DIP does not require DI — factories and service locators can also satisfy it.

Why It Matters

High-level modules should not depend on low-level implementations — both should depend on abstractions. This allows swapping implementations (real DB vs in-memory) without changing the module that uses them.

Common Mistakes

  • High-level service classes importing and instantiating concrete low-level classes directly.
  • Interfaces defined in the implementing module rather than the consuming module — inversion not fully achieved.
  • Injecting concrete types via constructor even when an interface exists — defeats the purpose.
  • Confusing DIP with DI (dependency injection) — DI is a mechanism; DIP is the principle about abstraction direction.

Code Examples

✗ Vulnerable
class OrderService {
  public function __construct() {
    $this->repo = new MySQLOrderRepository(); // concrete — hard to test
  }
}
✓ Fixed
class OrderService {
  public function __construct(
    private OrderRepositoryInterface $repo // depend on abstraction
  ) {}
}

Added 15 Mar 2026
Edited 22 Mar 2026
Views 33
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings F 0 pings S 1 ping S 0 pings M 1 ping T 1 ping W 0 pings T 0 pings F 0 pings S 2 pings S 0 pings M 0 pings T 0 pings W 0 pings T 1 ping F 0 pings S 1 ping S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 3 pings S 0 pings M 1 ping T 0 pings W 0 pings T 0 pings F
No pings yet today
No pings yesterday
Amazonbot 10 Perplexity 6 SEMrush 3 Unknown AI 2 Ahrefs 2 Majestic 1 Google 1
crawler 25
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: High
⚡ Quick Fix
High-level modules should depend on interfaces, not concrete classes — flip the dependency by defining an interface in the domain layer and implementing it in the infrastructure layer
📦 Applies To
PHP 5.0+ web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
Domain/service class importing concrete infrastructure class (Doctrine, Mailer, S3Client) directly
Auto-detectable: ✗ No phpstan psalm
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: High ✗ Manual fix Fix: High Context: Class Tests: Update

✓ schema.org compliant