Si dovrebbe usare Iniezione delle Dipendenze anche se la classe è usata una sola volta? [duplicare]

14

Durante una revisione del codice ho iniziato ad avere un po 'di dilemma se usare o meno l'iniezione di dipendenza. Mi piacerebbe sentire i tuoi pensieri, perché questo è una specie di tema in corso e sarebbe di aiuto anche per le future recensioni del codice.

Prima di iniziare, voglio dire che, dal mio punto di vista, DI viene utilizzato principalmente per la gestione delle dipendenze e per un test dell'unità più semplice e molto più semplice (correggimi se sbaglio per favore).

Ora ecco lo scenario:

Questa è la classe che verrà utilizzata come dipendenza solo una volta e probabilmente per sempre. Significa che rimarrà così per un po 'e nessun'altra classe lo userà.

L'essere di ragione è perché è un refactoring di qualche codice legacy e non c'era molto da fare, ma per separarlo in un'altra classe, almeno come primo buon passo, per seguire SRP .

Inoltre, un'altra cosa è che l'ipotetico doSomethingImportant () colpisce il database.

public SomeClass
{
   public Object doSomethingImportant()
   {
      ...
   }
}

Sulla base di queste informazioni pensi che sia giusto reinventare la dipendenza nell'altra classe invece di usare DI da:

il tipo di argomento della gestione delle dipendenze cade poiché verrà utilizzato solo una volta.

&

Anche il test delle unità cade poiché preferirei fare un test di integrazione o di accettazione per vedere come il metodo sta interagendo con il database in un'applicazione reale.

public SomeOtherClass
{
   private readonly SomeClass _someClass = new SomeClass();

   public Object doSomethingImportantUsingDependency()
   {
      ...
   }
}

Personalmente ero incline a fare DI perché è considerato una buona pratica, ma per un secondo ho sentito che stavo seguendo accecamente le regole e non ci pensavo da quando ci sono sempre delle eccezioni alla regola.

Che cosa pensi di questo? Mi piacerebbe sentire.

PS: non penso che sia una domanda generica "quando dovrei usare DI" perché è molto specifica per questa particolare situazione quando i test unitari non servono e la classe verrà usata solo una volta così non è necessario centralizzarlo per la gestione delle dipendenze (anche se è una buona pratica in generale).

    
posta AvetisG 08.04.2015 - 17:23
fonte

4 risposte

13

In C # è banale fornire un'iniezione di dipendenza facoltativa senza accoppiarsi troppo strettamente alla dipendenza:

public class SomeOtherClass {
    private readonly ISomeClass _someClass;

    public SomeOtherClass(ISomeClass dependency = null) {
        _someClass = dependency ?? new SomeClass();
    }
}

(oppure puoi rendere espliciti i costruttori se la tua azienda non apprezza i parametri predefiniti)

Nella mia esperienza, "oh non avremo mai bisogno di un altro" è ingenuo. Cambiamenti aziendali. La tecnologia cambia. Rendi flessibili le dipendenze.

E questo genere di cose colpisce il giusto equilibrio tra usabilità (si, quasi sempre si usa quello comune / predefinito) e flessibilità (ma il ctor è lì se ne hai bisogno) - il tutto con una linea semplice e semplice di codice, fornendo allo stesso tempo una parvenza di errore che corregge la robustezza. È così banale e chiaramente vantaggioso, non c'è ragione di non farlo per il caso semplice / diretto.

    
risposta data 08.04.2015 - 17:35
fonte
11

Esiste un principio di sviluppo sulla falsariga di DRY e SOLID chiamato YAGNI che è stato progettato per aiutare a semplificare i tuoi sforzi di sviluppo nel fare le cose e non rimanere paralizzato dall'indecisione su cosa fare.

Se in seguito trovi che è necessario migliorare la tua classe, allora lo farai. YAGNI dice di non preoccuparsi così tanto ora, perché probabilmente non avrai bisogno di spendere questo sforzo in più. Falla finita, torna indietro se è davvero necessario.

Alcuni dicono che è l'opposto di SOLID ma in realtà è tutto basato sul commercio di tutti i fattori coinvolti nello sviluppo, non hai tempo o risorse infiniti (e il codice 'perfetto' non è mai IMHO).

Quindi, qui dici che non ha bisogno della complessità DI ... quindi c'è la tua risposta. Non inserirlo. Passa a tutte le altre cose che devi fare.

    
risposta data 08.04.2015 - 17:41
fonte
5

Se non applichi DI fino a quando non ne hai davvero bisogno (nemmeno per il test dell'unità), non accadrà nulla di brutto. Il codice non diventa soggetto a errori, "eccessivamente complicato" o difficile da mantenere. E se decidi di rifattorizzare la dipendenza in un secondo momento, probabilmente non sarà molto più difficile che farlo ora. Questo è un caso in cui si applica il principio YAGNI.

Tuttavia, cosa dovresti controllare se sei sicuro di non voler essere in grado di testare il SomeOtherClass in isolamento da SomeClass , e se la dipendenza imposta dagli assembly dove SomeOtherClass e SomeClass live non diventerà un problema. Se sei sicuro al 100% che la risposta alle domande precedenti sia "sì", puoi ignorare DI.

    
risposta data 08.04.2015 - 20:25
fonte
0

La risposta come la maggior parte delle cose è "dipende".

Se vuoi testare unitamente la funzionalità in doSomethingImportantUsingDependency , dovrai essere in grado di iniettare la dipendenza.

Tuttavia, se tutto ciò che doSomethingImportantUsingDependency fa è una mappatura delle proprietà dal risultato della chiamata al database, sarebbe pragmatico non preoccuparsi.

Se qualche altra classe dipende da SomeOtherClass , puoi sempre iniettare quella classe.

    
risposta data 08.04.2015 - 17:37
fonte