SoatDev IT Consulting
SoatDev IT Consulting
  • About us
  • Expertise
  • Services
  • How it works
  • Contact Us
  • News
  • October 25, 2023
  • Rss Fetcher

Many articles talk about DIP, but few explain how to invert a dependency.

What Inversion Means in the Dependency Inversion Principle

By the end of the article, you will know how to invert dependencies and why it is not just about creating abstractions.

But before understanding how to invert a dependency, we need to understand what a dependency is.

A close-up to a stand of a modern library, there are books and magazines.
Image generated by Midjourney

What Is a Dependency?

A dependency is any component required to work. From the DIP perspective, a dependency is any code required to deploy another.

Examples

  • When you have a method that asks for arguments, your method depends on the data of those arguments. Furthermore, the types of those arguments are dependencies.
  • If you have a class whose properties require different types, those types are dependencies of your class.
// Book.swift

class Book {
let name: String
}
// Library.swift

class Library: {
var books: [Book]
}

In the above example, the type ‘Book’ is a dependency of Library because we can’t compile the library.swift if book.swift doesn’t exist.

What Is Dependency Inversion

The Dependency Inversion Principle (DIP) tells us that the most flexible systems are those in which source code dependencies refer only to abstractions, not to concretions.

– Robert C. Martin Clean Architecture.

Abstractions can be Interfaces in Java, Protocols in Swift, or Abstract Classes in other languages.

But just changing classes for abstractions doesn’t mean we are inverting a dependency.

How To Invert a Dependency

Let’s check again our example with the library.

// Book.swift

class Book {
let name: String
}
// Library.swift

class Library: {
var books: [Book] = []
}

I can’t compile the Library.swift file without compiling before the Book.swift means the Library depends on the Book file. This doesn’t seem correct because a library could store other kinds of items, like magazines.

So, let’s refactor our code.

// Book.swift

protocol Item {
let name: String
}

class Book: Item {
let name: String
}
// Library.swift

class Library: {
var items: [Item] = []
}

I changed my code to use an abstraction instead of a concrete type. Now I can inject into my Library any Item and not only Books. This is more flexible, but did I invert the dependencies?

No, the dependencies were not inverted.

Since the Item abstraction still lives in the Book.swift file. The Library.swift file still depends on that file. Without the book file, I can’t compile, deploy, or ship a Library. The Library still depended on Books; the Dependency Inversion Principle was not fulfilled.

Let’s move the Item abstraction to the Library file and see what happens.

// Book.swift

class Book: Item {
let name: String
}
// Library.swift

protocol Item {
let name: String
}

class Library: {
var items: [Item] = []
}

I have the same abstraction and classes; I just changed where the abstraction lives. But such a simple change makes the Library file independent of the Book file. I can now deploy Libraries even if the Book file doesn’t exist.

The Library no longer depends on the Book; the Book is the one that depends on the Library. The dependency was inverted.

But How Do I Know What Should Depend on What?

So, we refactored the code to invert the dependencies, but how do I know this is correct? What if I want to make books independent of libraries?

First, imagine you are designing the Library class, and it’s required to store a wide range of items, as long they have a name. If they fulfill this requirement, they can be stored in the Library. This means you will decide based on the Library’s needs rather than the Book’s.

But now you have a new dilemma. You want to deploy books without libraries. Because you also want to sell them in a bookstore. This problem can be solved easily by implementing the abstraction in a different file (or module).

// Library.swift

protocol Item {
let name: String
}

class Library: {
var items: [Item] = []
}
// Book.swift

class Book {
let name: String
}
// Book+Library.swift

extension Book: Library {}

🎉 With this change, Libraries and Books are independent of each other. What is important is that the abstraction (Item) is declared on the consumer (Library) side.


What inversion means in the Dependency Inversion Principle was originally published in Better Programming on Medium, where people are continuing the conversation by highlighting and responding to this story.

Previous Post
Next Post

Recent Posts

  • Drive Capital’s second act –  how the Columbus venture firm found success after a split
  • Ask not for whom the Louvre of Bluesky tolls, it tolls for thee
  • Transmission Obstacles and Ellipsoids
  • Google faces EU antitrust complaint over AI Overviews
  • Ready-made stem cell therapies for pets could be coming

Categories

  • Industry News
  • Programming
  • RSS Fetched Articles
  • Uncategorized

Archives

  • July 2025
  • June 2025
  • May 2025
  • April 2025
  • February 2025
  • January 2025
  • December 2024
  • November 2024
  • October 2024
  • September 2024
  • August 2024
  • July 2024
  • June 2024
  • May 2024
  • April 2024
  • March 2024
  • February 2024
  • January 2024
  • December 2023
  • November 2023
  • October 2023
  • September 2023
  • August 2023
  • July 2023
  • June 2023
  • May 2023
  • April 2023

Tap into the power of Microservices, MVC Architecture, Cloud, Containers, UML, and Scrum methodologies to bolster your project planning, execution, and application development processes.

Solutions

  • IT Consultation
  • Agile Transformation
  • Software Development
  • DevOps & CI/CD

Regions Covered

  • Montreal
  • New York
  • Paris
  • Mauritius
  • Abidjan
  • Dakar

Subscribe to Newsletter

Join our monthly newsletter subscribers to get the latest news and insights.

© Copyright 2023. All Rights Reserved by Soatdev IT Consulting Inc.