What is the dependency inversion principle and why is it important?
A much clearer way to state the Dependency Inversion Principle is:
Your modules which encapsulate complex business logic should not depend directly on other modules which encapsulate business logic. Instead, they should depend only on interfaces to simple data.
I.e., instead of implementing your class Logic as people usually do:
class Dependency { ... }
class Logic {
private Dependency dep;
int doSomething() {
// Business logic using dep here
}
}
you should do something like:
class Dependency { ... }
interface Data { ... }
class DataFromDependency implements Data {
private Dependency dep;
...
}
class Logic {
int doSomething(Data data) {
// compute something with data
}
}
Data and DataFromDependency should live in the same module as Logic, not with Dependency.
Why do this?
Dependency changes, you don't need to change Logic. Logic does is a much simpler task: it operates only on what looks like an ADT.Logic can now be more easily tested. You can now directly instantiate Data with fake data and pass it in. No need for mocks or complex test scaffolding.