Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →The Dependency Inversion Principle (DIP), the “D” in SOLID, says that high-level policy and low-level implementation should both depend on abstractions—not that policy code should depend directly on technical details. The abstraction should express a capability the policy needs, while infrastructure supplies an implementation of that contract.
What does the Dependency Inversion Principle mean?
DIP has two parts:
- High-level modules should not depend on low-level modules. Business rules should not be tied directly to specific infrastructure such as a database driver.
- Both should depend on abstractions. The high-level code relies on a contract that describes what it needs; low-level code implements that contract. The abstraction should not depend on implementation details.
The important question is not simply whether a design contains an interface. It is whether the dependency points at an abstraction at the right level. As Martin Fowler puts it, “DIP is about the shape of the object upon which the code depends.” Fowler’s discussion of DIP explores why the shape and level of that dependency matter.
As an Amazon Associate I earn from qualifying purchases.
How does DIP differ from dependency injection?
DIP describes a design relationship: which abstraction code depends on, and how that dependency is directed. Dependency injection (DI) describes how an object receives a dependency, such as through a constructor, setter, method argument, or container. TU Delft’s SOLID principles material discusses the two concepts in this context.
Injection alone does not establish DIP. An object can receive a concrete database connection through its constructor and still depend on a low-level mechanism. Inversion of control (IoC) is another related idea: it concerns who initiates an interaction, as when a framework calls application code through a callback. A DI container is one possible way to provide dependencies; using one is not the definition of DIP.
#1 Best Overall
Why a domain-level contract matters
Consider a Monopoly game object that needs to read the board. It could use a JDBC connection and issue SQL directly. Passing that connection into the game object would be dependency injection, but the game would still need to understand a database mechanism that is not part of the game’s domain.
A BoardRepository contract instead describes the capability the game needs. The game depends on that domain-level abstraction; a database-backed repository implements it. The database detail can then change without making the game’s rules depend on SQL or JDBC. Fowler uses this example to show why a technically abstract API can still be at the wrong level for the consumer.
A small code illustration
This language-neutral pseudocode illustrates the relationship; it is not a tested project or framework recipe:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
interface BoardRepository {
Board loadBoard()
}
class Game {
private BoardRepository boards
Game(BoardRepository boards) {
this.boards = boards
}
void start() {
Board board = boards.loadBoard()
// Apply game rules using the board
}
}
class SqlBoardRepository implements BoardRepository {
Board loadBoard() {
// Read and map the board using a database
}
}
The game’s policy-facing code names the operation it needs. The database-specific class supplies that operation. Application startup or a composition root can choose and provide the concrete repository, keeping implementation selection visible without making the game responsible for constructing its infrastructure.
Rank #3
When should you introduce an abstraction?
Start with a use case, not with a desire to add interfaces. Identify the capability the higher-level policy requires, name the contract in the consuming domain’s vocabulary, and include only operations current use cases need.
An abstraction should not merely wrap a lower-level API while exposing all of its irrelevant concerns. JDBC is an abstraction over database access, for example, but it may still force game logic to manage database concepts. Nor does the fact that a class has one implementation today automatically justify a generic interface designed for hypothetical future versions. Abstractions and extra factoring have a cost; add them when they clarify or protect a real boundary.
A practical DIP checklist
- Domain fit: Does the contract describe what the consuming policy needs, rather than how an implementation works?
- Dependency direction: Does high-level code depend on the contract while infrastructure implements it?
- Focused surface: Are the contract’s operations limited to current needs?
- Visible wiring: Is it clear where the concrete implementation is selected and supplied?
Use DI if it suits the application’s construction needs, but evaluate the abstraction separately: how a dependency is provided does not prove that the dependency is well designed.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minuteWhere the principle came from
The historical references distinguish between naming and introduction. Old Dominion University’s SOLID teaching material says Robert Martin named DIP in 1996. Fowler says Martin introduced him to the principle around 1994. These are different historical claims; they do not establish an exact first-publication date.
Best Value
TU Delft lists Robert C. Martin’s Agile Software Development: Principles, Patterns, and Practices (2002) as further reading. It is a broad book about software design and development, not a dedicated DIP manual or a requirement for understanding the principle.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




