# Dependency Inversion Principle (DIP) The **Dependency Inversion Principle (DIP)** is the "D" in [[SOLID Principles]]. It states two things: 1. **High-level modules should not depend on low-level modules. Both should depend on abstractions.** 2. **Abstractions should not depend on details. Details should depend on abstractions.** Coined by [[Robert C. Martin]] in his 1996 article *"The Dependency Inversion Principle"* (C++ Report). The "inversion" is relative to traditional procedural design, where business logic at the top calls implementation modules at the bottom, creating a top-down dependency chain. DIP flips that: the business logic depends on an abstraction it owns, and the implementation conforms to that abstraction. ## What it actually says In a naive design, a high-level policy module (`OrderProcessor`) imports a concrete low-level module (`PostgresOrderRepository`). Change the database, change the policy. Coupling at the wrong end. DIP introduces an abstraction (`OrderRepository` interface) that lives *with* the policy. The policy depends on the abstraction. The concrete implementation also depends on the abstraction (by implementing it). The dependency arrow now points *from* the detail *to* the abstraction; that's the inversion. ``` Before: Policy ──depends on──> Detail After: Policy ──depends on──> Abstraction <──implemented by── Detail ``` The abstraction is owned by — defined in the same module/package as — the high-level code. This is the part most often missed: it's not enough to extract an interface; the interface has to live with the consumer, not the provider. ## Why it matters - **Stable cores, swappable edges**: business rules don't change when infrastructure changes. - **Testability**: the abstraction can be replaced with a fake/mock in tests without touching the real implementation. - **Plugin architectures**: third parties extend the system by implementing the abstractions you defined. - **Vertical slices stay coherent**: the policy module is self-contained; it ships with its own port definitions. ## Common misunderstandings - **DIP ≠ "use interfaces everywhere"**. An interface that lives in the same package as its single implementation buys nothing. The point is the *direction* of dependency, not the presence of an interface keyword. - **DIP ≠ [[Dependency Injection (DI)]]**. DI is a *technique* for supplying dependencies; DIP is a *principle* about which way they should point. You can satisfy DIP without DI (factory methods, Service Locator), and you can use DI in a way that violates DIP (injecting a concrete type). - **DIP ≠ [[Inversion of Control (IoC)]]**. IoC is broader and about flow of control; DIP is narrower and about direction of source-code dependencies. ## Practical heuristic When module A would naturally import module B, but B is a *detail* (database, network, framework, third-party API), invert it: define an abstraction inside A that captures what A needs from B, then make B implement A's abstraction. The detail now points at the policy. ## References - Robert C. Martin — *The Dependency Inversion Principle* (C++ Report, May 1996) — https://web.archive.org/web/20110714224327/http://www.objectmentor.com/resources/articles/dip.pdf - Robert C. Martin — *Agile Software Development: Principles, Patterns, and Practices* (2002), Chapter 11 ## Related - [[Inversion of Control (IoC)]] - [[Dependency Injection (DI)]] - [[SOLID Principles]] - [[Liskov Substitution Principle (LSP)]] - [[Loose Coupling]] - [[High Cohesion]] - [[Composition over Inheritance]] - [[Robert C. Martin]]