Principio di inversione di dipendenza vs "Programma per un'interfaccia, non un'implementazione"


12

Sto cercando di capire come il principio di inversione di dipendenza differisca dal principio "programma a un'interfaccia, non a un'implementazione".

Capisco cosa significa "Programma per un'interfaccia, non per un'implementazione". Capisco anche come sia possibile realizzare progetti più flessibili e mantenibili.

Ma non capisco come il principio di inversione di dipendenza sia diverso dal principio "Programma a un'interfaccia, non a un'implementazione".

Ho letto di DIP in diversi punti del web e non ha chiarito la mia confusione. Continuo a non vedere come i due principi differiscano l'uno dall'altro. Grazie per l'aiuto.

Risposte:


25

"Programma su un'interfaccia" significa che non dipende da un tipo concreto per svolgere il tuo lavoro , ma non specifica come ottenere la tua dipendenza.

Il "Principio di inversione di dipendenza" afferma che un oggetto non dovrebbe controllare la creazione delle sue dipendenze, dovrebbe solo pubblicizzare la dipendenza di cui ha bisogno e lasciare che sia il chiamante a fornirlo . Ma non specifica se la dipendenza debba essere un tipo concreto o un'interfaccia.

Illustrerò le differenze con un po 'di codice C #.

L'esempio seguente dipende da un tipo concreto e controlla la creazione della propria dipendenza. Non segue "programma su un'interfaccia" né "inversione di dipendenza":

public class ThingProcessor
{
    MyThing _myThing;

    public ThingProcessor()
    {
        _myThing = new MyThing();
    }

    public void DoSomething()
    {
        _myThing.DoIt();
    }
}

L'esempio seguente dipende da un'interfaccia, ma controlla la creazione della propria dipendenza. Segue "programma su un'interfaccia", ma non "inversione di dipendenza":

public class ThingProcessor
{
    IMyThing _myThing;

    public ThingProcessor()
    {
        _myThing = ThingFactory.GiveMeANewMyThing();
    }

    public void DoSomething()
    {
        _myThing.DoIt();
    }
}

L'esempio seguente dipende da un tipo concreto, ma richiede che la sua dipendenza venga creata e passata ad essa. Segue "inversione di dipendenza", ma non "programma a un'interfaccia":

public class ThingProcessor
{
    MyThing _myThing;

    public ThingProcessor(MyThing myThing)
    {
        _myThing = myThing;
    }

    public void DoSomething()
    {
        _myThing.DoIt();
    }
}

L'esempio seguente dipende da un'interfaccia e richiede che la sua dipendenza venga creata e passata ad essa. Segue sia "inversione di dipendenza" che "programma a un'interfaccia":

public class ThingProcessor
{
    IMyThing _myThing;

    public ThingProcessor(IMyThing myThing) // using an interface
    {
        _myThing = myThing;
    }

    public void DoSomething()
    {
        _myThing.DoIt();
    }
}

1
Ottima illustrazione della differenza.
Rory Hunter,

8
Quello di cui stai parlando è l'iniezione depenendy. E l'inversione di dipendenza e l'iniezione di dipendenza sono due cose diverse.
Euforico

1
@Euforico Sto parlando del principio di inversione di dipendenza, che è un concetto astratto, usando l'iniezione di dipendenza come esempio di implementazione concreta. Capisco la differenza
Eric King,

1
@EricKing Quindi dovresti dire esplicitamente che nella tua risposta invece di andare "Il" Principio di inversione di dipendenza "dice ..." che è ovviamente sbagliato se leggi la mia risposta.
Euforico

1
Sono d'accordo con Euforico. Il principio di inversione di dipendenza afferma che i livelli di codice di livello superiore dovrebbero dipendere da parti di codice di livello inferiore, non viceversa. Ad esempio, PrintStreamdovrebbe dipendere dall'interfaccia stabilita da ByteOutputStream. Dependency Injection non menziona nulla su chi dovrebbe dipendere da chi.
Doval,

5

Sono generalmente la stessa cosa. Se leggi Cos'è il principio di inversione di dipendenza e perché è importante? e Principio di inversione di dipendenza , ti renderai conto che i due "principi" parlano sostanzialmente della stessa cosa.

  • I moduli di alto livello non dovrebbero dipendere da moduli di basso livello. Entrambi dovrebbero dipendere dalle astrazioni.
  • Le astrazioni non dovrebbero mai dipendere dai dettagli. I dettagli dovrebbero dipendere dalle astrazioni.

L'interfaccia è un'astrazione e l'implementazione è un dettaglio. Se li sostituisci nelle due precedenti dichiarazioni, otterrai sostanzialmente "il codice dovrebbe dipendere dalle interfacce e non dalle implementazioni". E mi sembra la stessa cosa.


Questa dovrebbe essere la risposta accettata, l'altra risposta più votata è fuorviante
Sameh Deabes,

2

Le interfacce sono un modo per implementare DI. Se si specifica un'interfaccia come parametro nel metodo di costruzione di una classe, è possibile passare qualsiasi oggetto che si desidera a quel metodo di costruzione, purché quell'oggetto implementi l'interfaccia del parametro di costruzione.

In altre parole, la programmazione di un'interfaccia consente di modificare l'implementazione di tale interfaccia. È così che siamo in grado di sostituire oggetti finti con oggetti reali durante i test delle unità, specificare diversi fornitori di dati e così via.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.