Dependency inversion principle

In object-oriented design, the dependency inversion principle is a specific methodology for loosely coupled software modules.

When the discovered abstract interaction schema(s) between two modules is/are generic and the generalization makes sense, this design principle also leads to the following dependency inversion coding pattern.

This architecture groups the higher/policy components and the abstractions that define lower services together in the same package.

In many projects the dependency inversion principle and pattern are considered as a single concept that should be generalized, i.e., applied to all interfaces between software modules.

There are at least two reasons for that: If the mocking tool used relies only on inheritance, it may become necessary to widely apply the dependency inversion pattern.

This has major drawbacks: The presence of interfaces to accomplish the Dependency Inversion Pattern (DIP) has other design implications in an object-oriented program: Using inheritance-based mocking tools also introduces restrictions: Two common implementations of DIP use similar logical architecture but with different implications.

But some higher-level modules may require a simpler way to browse the system: any person may have children, parents, siblings (including half-brothers and -sisters or not), grandparents, cousins, and so on.

It also permits embedding exact definitions of siblings or uncles in the genealogical module, thus enforcing the single responsibility principle.

Finally, if the first extensible generalized graph approach seems the most extensible, the usage of the genealogical module may show that a more specialized and simpler relationship implementation is sufficient for the application(s) and helps create a more efficient system.

A remote file server (FTP, cloud storage ...) client can be modeled as a set of abstract interfaces: If local and remote files offers the same abstract interfaces, high-level modules that implement the dependency inversion pattern can use them indiscriminately.

Instances of the ICustomerHandler interface are created dynamically by a Factory (possibly in the same Controllers package).

Example of DIP
Example of DIP