Dependency Inversion Principle (The “D” of SOLID Programming Principles)

Bryon Harris
arcanium
Published in
7 min readMar 16, 2023

The Dependency Inversion Principle is the “D” in SOLID Programming.

Take your coding up a notch with the Dependency Inversion Principle! The DIP will result in architectures that are:

  • More flexible!
  • More secure!
  • More stable!

The Book: https://amzn.to/3GPypMA

Transcripts (the following transcripts are auto-generated and may have typos or inaccuracies):

all right we’ve done it we’re at the d

The Dip the dependency inversion

principle which is the D in solid the

last of our solid uh programming

principles so

um what is the dependency inversion

principle and why have I been referring

to it in every single video because of

course it is last but not least it is

probably the most important thing here

um so while I’m stumbling over my words

we are going to continue and actually

learn what it means which is effectively

that the uh system will be more flexible

when your source code dependencies refer

to abstractions over concretions that is

that abstractions uh which hide the

implementation details when you import

those into a class or a module you’re

making your system more flexible when

you import the concretions that is the

units of code that that have the actual

implementation details you are making

your system more rigid and thus less

change tolerant and so the more we

invert these dependencies using the dip

the more flexible the system will be so

let’s get into it arcanium

welcome to a production by Dr Miles

Aaron

CEO and co-founder at arcanium ventures

don’t forget to subscribe subscribe

subscribe

alright so if you take the dependency

inversion Principle as this great thing

that you should apply to everything to

make your system more flexible at some

point your system is going to be so

flexible that it’s going to be a pain to

work with and you’re not going to be

able to get anything done so it becomes

obvious that we need some way of

thinking about this that doesn’t result

in putting some sort of interface or

adapter between every single function in

our code base and there are a couple

ways to think about this the way that

Uncle Bob shares that I think is is is

great

um is that you should think about the

volatility of those concrete classes or

concrete artifacts so

in your concretions you’ve got

implementation details that may be where

a function is actually described where

the function

um implementation details live and that

function may require some other

functions maybe they’re even language

built-in functions or maybe they’re just

some private methods that are also

concrete and you don’t need interfaces

between those because

um

they have this High cohesion and they’re

stable and so what Uncle Bob says is

look focus on the volatility of your

concrete abstractions so if it’s highly

volatile it’s probably something that

could cause issues if it’s extremely

stable

um then it’s probably something you

don’t need to worry about as much and

what the dip or dependency inversion

principle teaches us is that we should

favor favor

um stable interfaces so when you make

um your uh abstractions extremely stable

that means that you can rely on other

principles like liskov

basically we’re using open close

principle here we’re making that

interface very stable so that the um the

concrete Parts can be substituted in and

out or we can even change the concrete

Parts

um but we don’t really require any

change to our interface because we are

following that open closed principle and

list of substitution Principle as

described in previous videos and so

um

this gives you a way to kind of focus

your energy rather than making this

system that has way too many degrees of

freedom in a lot of ways I like to think

of software as when you when you add

these

abstractions these these layers in

between that don’t carry the

implementation details

um it’s kind of like you’re adding a

degree of freedom to a um to a mass

spring damper system in engineering or

mechanical engineering vibrations and as

you can imagine if you have this system

of Springs and masses and as you’re

adding more connectors and more Springs

and more hinges and eventually you get

this system that’s just floppy and

unusable and chaotic right and so you do

want to have

um

some control and some thought behind

this and the way to do that is according

to volatility now one way you can make

this practical is just look at your code

base all the git analytics are right

there for you and you can see which

um concrete uh parts of my code base

which implementation details are getting

the most traffic and the most changes

um well if that means they’re very

volatile I want to make sure that I have

a stable

um abstraction that they’re connected to

a stable interface so that it can

insulate the rest of my code base from

that instability just a bit and you can

use the dependency inversion principle

to accomplish that another way to think

about all this that I think is really

practical is to say that I want to put

all of my business logic in my

abstractions so the real you know meat

of what the application does is in the

abstractions and all the implementation

deal details are in the concretions and

so this idea of having your concrete

components flowing toward your abstract

components it allows us to say that

effectively the source code dependencies

are going against the flow of control

and that is all dependency inversion

really is and as you separate your

abstract components from your concrete

components and you have stable

interfaces to deal with the volatility

of those volatile concrete

implementation details you’ve

effectively set up an architectural

boundary and so as we go from thinking

about this in terms of you know classes

and functions and modules up until

components and then we start looking at

entire architectures

this becomes the the dependency

inversion principle leads to actual

architectural boundaries where you’re

saying hey this is a boundary between

abstract and concrete I can see that

there’s going to be something else on

the other side of that line and that

starts to to break your architecture

ultimately into domains if you’re

following some kind of domain driven

design but does create this

um this kind of high level

decoupling of of architectural domains

not just components and modules and

functions like so many things it’s like

software architecture is a big fractal

man

so now I want to talk about just three

ways briefly that you can use the

dependency inversion principle what

patterns that creates in your software

one example that I use all the time is

called the adapter pattern what is the

adapter pattern put simply it’s a way to

put a square peg in a round hole so when

you’re using the adapter pattern what

you’re doing is saying I want to be be

able to adapt this thing into that thing

and

[Music]

in practice that may look something like

a payment system for example where you

want to be able to use a stripe payment

processor or the Paypal payment

processor or some other payment

processor that comes along the way

without having to

um

re-do your application rewrite your

application code and so you use the

adapter pattern to have a little adapter

in between that allows different payment

processors to be plugged in without

changing any of the business Logic on

the abstract side of that architectural

boundary now

another pattern that will emerge is the

facade pattern so where the adapter is

talking about the Square Peg and the

round hole the facade pattern is more

about interoperability

of a kind of more complex system than

just one to one so I like to think of

the facade pattern and others have said

this as well as more of a control panel

it’s like abstracting away all of the

implementation details of a much more

complex system potentially you don’t

know how complex it is but it just gives

you some some knobs and some switches

and so it’s just kind of taking that

adapter pattern up a notch to create an

entire interface to another system where

the implementation details are

completely hidden and so the last

pattern that you’ll see emerge from the

dependency inversion principle that

we’ll talk about today is Factory

patterns and there are a few different

Factory patterns you can check out we’re

not going to to cover the details right

now but in general a factory pattern is

effectively

taking some disparate objects that

um or some objects that are created in

disparate places and creating a factory

to create them at one location to create

that abstract interface again to bring

what was

um putting implementation details on the

abstract side and bringing it into the

concrete side of your architecture

effectively it it changes where objects

are made so that where the objects are

used is not where they are created so

put simply since I just bungled the hell

out of that factories can be used to put

to separate where objects are used from

where objects are made and typically you

are going to make those objects in the

concrete side of your architecture

you’re going to use a factory to bridge

from concrete side to the abstract side

in order to allow your application

details to only depend on that factory

so that it can use those objects without

having connections to the details around

how those objects are made so we have

the adapter we’ve got the facade pattern

we’ve got factories the dependency

inversion principle you should check out

dependency injection which uses very

similar Concepts as well

um and you’ll be Off to the Races

hopefully you enjoyed this series on

solid I have to jump into a meeting so I

will see you on our next journey into

software architecture we’ve covered all

the basics now I think to a reasonable

level

um so I hope that we’ll get into some

more

um exciting architectures and start

looking at some open source repos real

soon see you next time

--

--