# Principio di inversione delle dipendenze

Nella programmazione orientata agli oggetti, il principio di inversione delle dipendenze (o della dipendenza; in inglese dependency inversion principle, abbreviato in DIP) è una tecnica di disaccoppiamento dei moduli software, che consiste nel rovesciare la pratica tradizionale secondo cui i moduli di alto livello dipendono da quelli di basso livello. Il principio fu formulato per la prima volta da Robert C. Martin, che lo sintetizzò nel seguente modo:
       I moduli di alto livello non devono dipendere da quelli di basso livello. Entrambi devono dipendere da astrazioni;
       Le astrazioni non devono dipendere dai dettagli; sono i dettagli che dipendono dalle astrazioni.
Il principio di inversione delle dipendenze è uno dei cinque principi SOLID della programmazione a oggetti. Nella sua presentazione del principio, Martin lo descrisse come una generalizzazione dell'applicazione combinata di altri due principi SOLID, il principio aperto/chiuso e il principio di sostituzione di Liskov.
L'inversione delle dipendenze è un concetto correlato, ma non del tutto sovrapposto, a quello dell'inversione del controllo.

## Descrizione

Nella pratica convenzionale della programmazione, i componenti software sono organizzati in una gerarchia di astrazione che coincide con una gerarchia di uso e definisce una corrispondente struttura di dipendenze. In altre parole, i componenti di alto livello realizzano le proprie funzioni facendo uso di componenti di più basso livello, attraverso le interfacce esposte da questi ultimi, e questo normalmente implica una dipendenza dei componenti di alto livello da quelli di basso livello. Questa dipendenza si può concretizzare, per esempio, in una dipendenza di compilazione: per compilare il sorgente di un modulo di alto livello si deve far riferimento ai moduli di basso livello che il componente di alto livello usa e a cui quindi, normalmente, si riferisce nel proprio sorgente.
Il principio dell'inversione delle dipendenze ha lo scopo di impedire che le dipendenze riproducano in questo modo la gerarchia d'uso e di astrazione. Anziché riferirsi direttamente alle interfacce dei componenti di basso livello, i componenti di alto livello fanno solo riferimento ad astrazioni del funzionamento di tali componenti. Alle stesse astrazioni fanno riferimento i componenti di basso livello. Il riferimento è diverso nei due casi: un componente di alto livello usa determinate astrazioni, mentre uno di basso livello le implementa. Entrambe queste relazioni possono concretizzarsi in dipendenze di compilazione, nel senso che sia la compilazione dei componenti di alto livello che quella dei componenti di basso livello viene fatta con riferimento alle astrazioni usate come "collante"; tuttavia, non si instaura nessuna dipendenza di compilazione dai componenti di alto livello a quelli di basso livello. Poiché la definizione delle astrazioni "usate" da un componente di alto livello è concettualmente a carico di tale componente, e quindi solitamente appartiene allo stesso "contesto" (per esempio package o namespace), la dipendenza del componente a basso livello dall'astrazione è di fatto una dipendenza dal componente di basso livello a quello di alto livello, da cui l'idea che la dipendenza sia "invertita" rispetto a quella tradizionale.
L'obiettivo dell'inversione delle dipendenze si può ottenere con una varietà di metodi, principalmente fondati sul concetto di interfaccia o di classe astratta. Fra le tecniche più comuni che consentono di applicare l'inversione delle dipendenze si possono citare i design pattern Observer, Adapter, Factory Method e Abstract Factory, e la dependency injection.