L'iniezione di dipendenza a mano è un'alternativa migliore alla composizione e al polimorfismo?


13

Innanzitutto, sono un programmatore entry level; In effetti, sto finendo una laurea AS con un progetto finale capstone durante l'estate. Nel mio nuovo lavoro, quando non c'è alcun progetto da fare (stanno aspettando di riempire il team con più nuovi assunti), mi sono stati dati dei libri da leggere e da cui imparare mentre aspetto - alcuni libri di testo, altri non così tanto (come il codice completo). Dopo aver esaminato questi libri, mi sono rivolto a Internet per imparare il più possibile e ho iniziato a conoscere SOLID e DI (abbiamo parlato del principio di sostituzione di Liskov, ma non di molte altre idee SOLID). Quindi, come ho imparato, mi sono seduto per fare per imparare meglio e ho iniziato a scrivere del codice per utilizzare DI manualmente (non ci sono framework DI sui computer di sviluppo).

Il fatto è che, mentre lo faccio, noto che mi sembra familiare ... e sembra che sia molto simile al lavoro che ho fatto in passato usando la composizione di classi astratte usando il polimorfismo. Mi sto perdendo un quadro più grande qui? C'è qualcosa in DI (almeno a mano) che va oltre? Capisco la possibilità di avere configurazioni non nel codice di alcuni framework DI che abbiano alcuni grandi benefici per quanto riguarda il cambiamento delle cose senza dover ricompilare, ma quando lo faccio a mano, non sono sicuro che sia diverso da quanto sopra indicato ... Alcuni approfondimenti su questo sarebbe molto utile!

Risposte:


21

L'idea fondamentale in DI è semplicemente quella di spingere le dipendenze negli oggetti, piuttosto che lasciarle estrarre dall'esterno. Questo è stato anche chiamato "inversione di controllo" in precedenza. Ciò consente di controllare le dipendenze molto meglio e, ultimo ma non meno importante, di scrivere codice che è facile da testare l'unità.

I framework DI si basano solo su questa idea e automatizzano (in parte) la parte spesso noiosa del cablaggio delle dipendenze degli oggetti. In caso contrario, ciò potrebbe richiedere una notevole quantità di codice in un progetto più ampio, se fatto a mano.

Per definire le dipendenze, oltre ai file di configurazione esterni, al giorno d'oggi è anche possibile utilizzare le annotazioni del codice, ad esempio in linguaggi come Java e C #. Questi possono portare il meglio di entrambi i mondi: cablare le dipendenze in uno stile dichiarativo, ma proprio all'interno del codice stesso, a cui logicamente appartiene. Per me, la possibilità di cambiare le dipendenze senza dover ricompilare non è così preziosa, come accade raramente nella vita reale (a parte alcuni casi speciali), ma introduce una separazione spesso artificiale delle dipendenze dalle classi e dagli oggetti definiti nel codice .

Per tornare alla domanda sul titolo, DI non è un'alternativa alla composizione né al polimorfismo; dopo tutto, è reso possibile da questi due.


1
Dependency Injection (DI) è una forma di Inversion of Control (IoC).
Matthew Flynn,

@MatthewFlynn, davvero. Per riferimento: martinfowler.com/articles/injection.html
Péter Török

1
Questo è il mio riferimento. Parla dei nuovi "contenitori leggeri" che fanno inversione di controllo, cosa che era già comune poiché i listener di eventi UI erano una forma di IoC. Dubba l'oggetto che lega Spring e altri contenitori IoC come Iniezione di dipendenza per differenziarlo dall'altra forma di Inversione del Controllo.
Matthew Flynn,

Oops - Mi è mancato il "davvero". Pensavo mi stessi contraddicendo ... Scusa.
Matthew Flynn,

Il tuo ultimo paragrafo mi fa sentire un po 'meglio; per tutto il tempo in cui lavoravo al mio piccolo progetto di apprendimento, continuavo a ripetermi "questo sembra polimorfismo ..". Sfortunatamente, .Net ec # al mio lavoro è orribilmente obsoleto, ma esaminandolo, Unity è il framework c # incorporato di cui stai parlando?
Drake Clarris,

22

Il miglior articolo che abbia mai letto sull'argomento è stato quello di James Shore . Faccio " DI a mano " da secoli, come parte dell'astrazione e del polimorfismo. Quindi, dopo essere entrato nel mondo professionale e ho continuato a sentire quel termine, ho avuto una grande disconnessione tra ciò che pensavo dovesse significare la parola e ciò che effettivamente significa:

"Iniezione delle dipendenze" è un termine di 25 dollari per un concetto da 5 cent.

Viene dal post di Shore, che mi ha chiarito tutto. Per esempio:

Dato

class Engine {public abstract void start()}
class V8 extends Engine {...}
class V6 extends Engine {...}

Invece di scrivere:

class Car
{
    private Engine engine;
    public Car()
    {
        this.engine = new V6();
    }

    public void start()
    {
        this.engine.start();
    }
}

Scrivi qualcosa del genere:

class Car
{
    private Engine engine;
    public Car(Engine a)
    {
        this.engine = a;
    }

    public void start()
    {
        this.engine.start();
    }
}

...

Car F = new Car(new V8());

E questo impedisce Carall'istanza di gestire Enginedettagli specifici . Un'auto ha solo bisogno di un motore, non importa quale fintanto che implementa la funzionalità di base del motore. Cioè, la tua Carclasse non è legata alla dipendenza specifica dell'implementazione; è "iniettato" altrove, potenzialmente in fase di esecuzione.

Questo esempio specifico di Car utilizza il sottotipo di DI chiamato "Iniezione del costruttore", il che significa semplicemente che la dipendenza è stata consegnata come argomento del costruttore. Puoi anche usare un setEngine(Engine a)metodo per "Setter Injection" e così via, ma questi sottotipi mi sembrano pedanti.

Un po 'più avanti, tuttavia, molti framework DI forniscono la piastra di caldaia per collegare tra loro un mucchio di queste cose con riferimenti più astratti.

Questo è tutto.


0

Non sono un esperto poiché ho iniziato a utilizzare DI solo negli ultimi due anni, ma alcuni dei temi / funzionalità utili dei contenitori DI che ho notato sono (che non considero prodotti di composizione / polimorfismo (ma potrei essere corretto su questo):

  • fulcro centrale della creazione di oggetti
  • fornire singleton per thread
  • tecniche orientate all'aspetto come l'intercettazione

0

Oltre a DI, esiste una configurazione della composizione di classe nell'applicazione root (invece di configurare usando xml). Non è necessario alcun framework DI o IoC, anche se possono riordinare la configurazione della composizione della classe, in particolare per progetti di grandi dimensioni. Questo perché normalmente il framework DI viene fornito con un contenitore che implementa funzionalità aggiuntive, come il cablaggio automatico, che consente di configurare la composizione della classe. Puoi leggere il mio post sul blog per estrarre la mia comprensione su questo argomento.

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.