Dependency Inversion Principle vs "Programma su un'interfaccia, non su un'implementazione"

11

Sto cercando di capire in che modo il principio di inversione delle dipendenze differisce dal principio "programma in un'interfaccia, non in un'implementazione".

Capisco cosa significa "Programma su un'interfaccia, non un'implementazione". Capisco anche come permette di progettare più flessibili e manutenibili.

Ma non capisco come il principio di inversione delle dipendenze 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. Non vedo ancora come i due principi differiscano l'uno dall'altro. Grazie per il tuo aiuto.

    
posta Aviv Cohn 04.04.2014 - 01:03
fonte

3 risposte

24

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

Il "principio di inversione di dipendenza" dice che un oggetto non dovrebbe controllare la creazione delle sue dipendenze, dovrebbe solo indicare quale dipendenza ha bisogno e lasciare che il chiamante fornisca . Ma non specifica se la dipendenza debba essere un tipo concreto o un'interfaccia.

Illustrerò le differenze con un codice C #.

L'esempio seguente dipende da un tipo concreto e controlla la creazione della propria dipendenza. Segue il programma "a 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 su 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 sia creata e passata ad essa. Segue sia il programma "inversione di dipendenza" che "a un'interfaccia":

public class ThingProcessor
{
    IMyThing _myThing;

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

    public void DoSomething()
    {
        _myThing.DoIt();
    }
}
    
risposta data 04.04.2014 - 01:26
fonte
3

Sono generalmente la stessa cosa. Se leggi Qual è il principio di inversione delle dipendenze e perché è importante? e Principio di inversione delle dipendenze , realizzerete i due "principi" parla fondamentalmente 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 precedenti due dichiarazioni, ottieni fondamentalmente "il codice dovrebbe dipendere dalle interfacce e non dalle implementazioni". E sembra la stessa cosa per me.

    
risposta data 04.04.2014 - 08:24
fonte
2

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

In altre parole, la programmazione di un'interfaccia consente di modificare l'implementazione di tale interfaccia. È così che siamo in grado di sostituire gli oggetti mock per oggetti reali durante i test unitari, specificare diversi fornitori di dati e così via.

    
risposta data 04.04.2014 - 01:12
fonte

Leggi altre domande sui tag