> ## Documentation Index
> Fetch the complete documentation index at: https://meta.niceshare.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Dependency Inversion Principle

> Dependency Inversion Principle says high-level policy should not depend on low-level details. Origin, Java JDBC, and limits.

<Info>
  **Category**: Principles<br />
  **Type**: Systems design principle<br />
  **Origin**: Robert C. Martin, Engineering Notebook, *C++ Report*, 1996<br />
  **Also known as**: DIP; depend on abstractions, not concretions; the D in SOLID
</Info>

<Note>
  **Quick Answer** — The **Dependency Inversion Principle** says high-level policy must not depend on low-level details; both should depend on abstractions, and details should depend on those abstractions. Robert C. Martin named it in a 1996 *C++ Report* column after a copy program that could not change printers without rewriting the policy. The practical test is simple: if swapping a vendor, device, or person forces you to rewrite the rule, the rule depended on the wrong thing.
</Note>

## What is the Dependency Inversion Principle?

The Dependency Inversion Principle is a design rule that a policy module should depend on an abstraction it owns, not on the concrete mechanism that happens to carry the policy out today.

> High level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions.

That is not a plea for more interfaces. It is a rule about *who is allowed to force a rewrite*. Policy is the reason the system exists: copy this, pay that, admit these students. Details are keyboards, printers, Oracle drivers, and the cousin who currently drives the bus. If policy imports the detail, every swap of the detail reopens the policy.

The everyday picture is a wall socket. A kettle is not soldered into the plaster. The house publishes a socket. Kettles, lamps, and phone chargers plug in. If you hard-wire the kettle, a broken element means ripping the wall. The [Open-Closed Principle](/principles/open-closed) wants new kettles without editing the house. This principle says *which way the wire may run*: the house does not depend on a brand of kettle. The kettle depends on the socket the house already defined.

In code, a `Copy()` function that calls `ReadKeyboard()` and `WritePrinter()` by name does the same solder job. A new disk writer then forces an `if` into the policy, and the next device another `if`. The bruise is rigidity: the important module cannot be reused, and it cannot be tested, without dragging the hardware along. [Separation of concerns](/principles/separation-of-concerns) splits the jobs. This principle splits the *direction of the source dependency*.

### Dependency Inversion Principle in 3 Depths

* **Beginner**: Do not solder the lamp to the house. Publish a socket. Then a different lamp can plug in without rewriting the wiring diagram.
* **Practitioner**: Let policy depend on a port it defines. Put the vendor, file, or person behind that port. If a change of brand edits the rule, the arrow still points the wrong way.
* **Advanced**: Runtime still flows from policy into details. What inverts is the *source-code* arrow. The high-level module owns the abstraction, so details plug inward. A wrapper owned by the vendor is not inversion. It is the old dependency with an extra name.

## Origin

The Dependency Inversion Principle began as a coupling diagnosis in object-oriented C++, not as a slogan about dependency-injection frameworks.

**Robert C. Martin** stated it in *The Dependency Inversion Principle*, the third of his Engineering Notebook columns for *C++ Report* (**May 1996**). He had already argued, in *Object Oriented Design Quality Metrics: an analysis of dependencies* (**1994**), that the direction of source dependencies decides whether a design goes rigid. The 1996 column gave the rule a name. Traditional structured design, he wrote, tends to make high-level modules depend on low-level ones, and abstractions depend on details. He called the repair an *inversion* of that habit.

The paper’s working wound is a `Copy` program on a machine with no device-independent I/O. The policy loops: read a character from the keyboard, write it to the printer. `Copy` therefore depends on `ReadKeyboard` and `WritePrinter`. Add a disk file, and the policy sprouts a boolean and an `if`. Martin’s fix is two abstractions, `Reader` and `Writer`, owned beside `Copy`. Keyboard and printer implement them. The dependencies invert: details depend on the policy’s sockets. He notes that C’s `stdio.h`—`getchar` and `putchar`—is the same shape without classes.

*Agile Software Development: Principles, Patterns, and Practices* (Prentice Hall, **2003**) restates the two clauses and adds the Button/Lamp picture. A button that names `Lamp` cannot later switch a motor. A `ButtonClient` or `Switchable` socket lets the lamp plug in. Around **2004**, **Michael Feathers** arranged Martin’s “first five” principles into the SOLID mnemonic. The Dependency Inversion Principle is the “D.”

In *Clean Architecture* (Prentice Hall, **2017**) Martin widened the same arrow into the Dependency Rule: source dependencies point inward, toward policy. **Martin Fowler**’s *Inversion of Control Containers and the Dependency Injection Pattern* (**23 January 2004**) named a *wiring* technique—constructor, setter, and interface injection. That article is about how an object *receives* a neighbor. It is not a rename of this principle. The [Interface Segregation Principle](/principles/interface-segregation) was the next *C++ Report* column, and asks a different question: once you have a socket, is it too wide?

## Key Points

The Dependency Inversion Principle earns its keep when policy must outlive the current mechanism. It is not a ban on calling concrete code. It is a rule about which names the important module is not allowed to mention.

<Steps>
  <Step title="Invert the source arrow, not the runtime call">
    At run time, the button still tells the lamp to turn on. What changes is compile-time knowledge. Policy must not import, subclass, or construct the detail. The detail must implement a type the policy already defined. If the high-level file still names `OracleDriver`, the arrow did not invert. You added a hop.
  </Step>

  <Step title="The high-level module owns the socket">
    An interface living in the vendor’s package is the vendor’s face, not yours. Martin’s point is ownership: `Copy` specifies `Reader` and `Writer`. Keyboard and printer *conform*. A school that writes “must drive our Saturday route” owns the role. A school that writes “must be Cousin Wei’s van” has given the cousin the socket. [Liskov substitution](/principles/liskov-substitution) then asks whether the next van can actually stand in.
  </Step>

  <Step title="Do not let details leak through the abstraction">
    A `Database` port that returns `OracleResultSet`, or a “bus operator” contract that requires one company’s radio protocol, is a socket with the old plug glued on. Callers still compile against the detail. Keep vendor types, file formats, and person-specific habits behind the port. The [Single Responsibility Principle](/principles/single-responsibility) keeps policy from growing extra reasons to change. This principle keeps those extra reasons from being *imported*.
  </Step>

  <Step title="Do not invert what does not vary">
    `String`, a stable language list, and a one-off script that will die with its file do not need a port. [YAGNI](/principles/yagni-principle) applies: invent the socket when a second mechanism is real, or when tests must replace the first. An interface per class is ceremony. The cost is navigation, and a fake sense that the design is already flexible.
  </Step>
</Steps>

## Applications

Use the Dependency Inversion Principle when the rule should survive a change of tool, vendor, or person. Do not use it to wrap every object you already trust.

<CardGroup cols={2}>
  <Card title="Put a port between the rule and the I/O">
    Billing should depend on `Clock` and `Mailer`, not on `System.now` and last year’s SMTP class. Write the port next to the policy. Adapt the vendor behind it. When the mail provider changes, the invoice rules do not reopen.
  </Card>

  <Card title="Hire the role, then plug a person in">
    A weekend roster that names one uncle’s phone number is soldered. Write the duties: licensed, insured, Saturday 7 a.m. The named person is one implementer. A substitute can plug in without rewriting the school’s policy. That is this principle applied to a job, not only to a class.
  </Card>

  <Card title="Publish a public socket, not a branded appliance">
    Wall outlets, USB, and a city form that accepts “any licensed electrician” are the same cut. Citizens should not rebuild the house to change a kettle. If a public service hard-codes one vendor’s portal, every procurement cycle rewrites the service. Standardize the socket; let brands compete behind it.
  </Card>

  <Card title="Replace the real mechanism with a fake in tests">
    Early-career code that `new`s a live database cannot be checked on a train. Depend on a port, pass a fake that returns known rows, and keep the policy tests free of the network. You are not “doing Spring.” You are making the important module runnable without its current hardware.
  </Card>
</CardGroup>

## Case Study

The numbered public window onto the Dependency Inversion Principle is **Java Database Connectivity (JDBC)**—not a claim that one database API is the whole of architecture.

Sun specified JDBC in **January 1997** and shipped it with **JDK 1.1** on **19 February 1997**. The API is two layers on purpose. Application code talks to `java.sql.Connection`, `Statement`, and `ResultSet`. Vendors implement `java.sql.Driver`. `DriverManager.getConnection` looks up a driver that can handle the URL. A payroll module therefore compiles against `java.sql`, not against `oracle.jdbc` or a MySQL client. Swap the jar, keep the policy. That is Martin’s inverted arrow in a platform library: high-level code and low-level drivers both depend on the same abstractions, and the details (the drivers) depend on those abstractions.

The 1996 JDBC draft already split “API for application writers” from “JDBC Driver API.” Java **SE 6** (**11 December 2006**) added JDBC 4.0 service loading: a driver ships `META-INF/services/java.sql.Driver` and the platform can find it without `Class.forName`. As of **Java SE 26** (**2026**), the `java.sql` module still exports those interfaces. OpenJDK’s `Connection` type is marked `@since 1.1`. The inversion has outlived several generations of databases.

Boundary note: JDBC does not make SQL portable. A policy that embeds Oracle outer-join syntax still depends on a detail, even if every type is `java.sql`. `DriverManager` itself is a concrete locator; later teaching prefers `DataSource`. The lesson for new design is the 1997 split of policy from driver, not the claim that a standard API erases dialect. If the next database still forces you to rewrite queries, you inverted the types and left the language soldered.

## Boundaries and Failure Modes

The Dependency Inversion Principle fails when the detail is stable and local. Wrapping `String`, `Math`, or a one-file script behind `IString` adds types without buying a second implementation. The socket is a cost. Pay it where a second mechanism, a test double, or a vendor swap is real.

It also fails when the abstraction is owned by the detail. An `IOracleConnection` in the driver package, or a “standard” form that still requires one company’s attachment layout, leaves policy chasing the vendor. Inversion is not the presence of an interface. It is the direction of ownership.

The common misuse is treating a dependency-injection container as the principle. A container can inject a concrete `OracleRepository` into a concrete `PayrollService` that still imports Oracle types. The wiring is inverted. The dependency is not. Another misuse is an interface per class, then a maze of types that still change as a set. [Law of Demeter](/principles/law-of-demeter) still applies after inversion: talking to a socket does not license digging through the object you were handed to reach its inner vendor.

## Common Misconceptions

The English name collides with “dependency injection,” with “every class needs an interface,” and with the Hollywood line “don’t call us, we’ll call you.”

<AccordionGroup>
  <Accordion title="The Dependency Inversion Principle is the same as dependency injection">
    Injection is a delivery method: a constructor argument, a setter, or a framework hands you the neighbor. Inversion is a dependency rule: that neighbor is typed as a policy-owned abstraction, not as a vendor class. You can inject a concrete Oracle helper and still violate the principle. You can construct a `KeyboardReader` in `main` and still satisfy it, because `Copy` never named the keyboard.
  </Accordion>

  <Accordion title="The Dependency Inversion Principle means every class gets an interface">
    Martin inverted `Copy` against `Reader` and `Writer` because those mechanisms were expected to change. He did not demand a port in front of every integer. Stable language types, private helpers, and a module with one concrete life do not earn a socket. An interface whose only implementer will always be itself is a hat on a hat.
  </Accordion>

  <Accordion title="The Dependency Inversion Principle is the Hollywood principle">
    “Don’t call us, we’ll call you” inverts *who starts the conversation*—a framework calls your plugin. This principle inverts *which names a source file is allowed to mention*. Event loops, callbacks, and containers can help. They can also call concrete details. Owning the socket is the test, not whether a framework rang first.
  </Accordion>
</AccordionGroup>

## Related Concepts

These pages sit next to the same problem: how to keep the important rule from being rewritten every time the current tool, vendor, or person changes.

<CardGroup cols={3}>
  <Card title="Open-Closed Principle" href="/principles/open-closed">New details should plug in without editing policy. This principle says the plug must point at an abstraction the policy owns.</Card>
  <Card title="Liskov Substitution Principle" href="/principles/liskov-substitution">A plugged-in detail must honor the socket. A lamp that cannot turn off is not a substitute, even if it implements `Switchable`.</Card>
  <Card title="Interface Segregation Principle" href="/principles/interface-segregation">Once you have a socket, do not make callers depend on holes they will never use. Inversion without segregation is a fat plug.</Card>
  <Card title="Single Responsibility Principle" href="/principles/single-responsibility">Policy should have one reason to change. Inversion stops extra reasons from being imported as concrete names.</Card>
  <Card title="Separation of Concerns" href="/principles/separation-of-concerns">Keep policy and mechanism apart. This principle sets the direction of the remaining dependency between them.</Card>
  <Card title="Law of Demeter" href="/principles/law-of-demeter">Talk to your immediate socket. Do not reach through it into the vendor’s inner objects.</Card>
</CardGroup>

## One-Line Takeaway

<Tip>
  If swapping a tool, vendor, or person forces you to rewrite the rule, the rule depended on the wrong thing—own the socket, and let details plug in.
</Tip>
