The DIP states:
- High-level modules should not depend on low-level modules. Both should depend on abstractions.
- Abstractions should not depend upon details. Details should depend upon abstractions.
And the OCP states:
Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.
I think if we satisfy the DIP, it will cover the OCP too, So, why we separate these two principles?
The OCP makes a dependent class easy to consume. The OCP enables asynchronous consumption of an interface by decoupling old implementations from newer versions. It allows the things that depend upon it to continue to depend on it even in the face of change for other purposes. That way a class never has to care who's calling it.
The DIP does a couple of things. It makes depending on external classes easy. Dependency Injection enables the substitutions of dependencies by encouraging the separation of creation duties from consumption. Instead of creating the external dependency that is to be consumed, the pattern states that it should be provided externally. Ultimately, this encourages code that is idempotent (code that does not change external state). Idempotent code is good because it can be verified that it does only what is immediately visible. It doesn't have external side effects. It's very testable, understandable, and readable.