Modulo che richiede vs Iniezione di dipendenza in Javascript

18

In questi giorni mi è venuta in mente una domanda:

Does the way we Javascript go against almost everything that is considered a good practice in traditional Software Development?

Ho una serie di domande / osservazioni relative a questa affermazione, ma per rispettare il formato di StackExchange, sarà meglio se li divida in diverse domande.

Modulo che richiede

Il codice Javascript standard al giorno d'oggi assomiglia a:

const someModule = require('./someModule')

module.exports = function doSomethingWithRequest() {
  // do stuff
  someModule.someFunc()
  // do other stuff
}

vantaggi

  • Incapsulamento: il modulo funziona in modo indipendente e conosce tutto ciò di cui ha bisogno per svolgere le sue funzioni.
  • Essendo un colorary, è più facile per i client usare il modulo.

Svantaggi

  • Scarsa testabilità: è standard quando non si usa DI, ma in linguaggi dinamici, come Javscript, può essere aggirato * da moduli come mockery o rewire .
  • Sicuramente viola il DIP - da non confondere con Iniezione delle dipendenze. - dal momento che posso importare solo moduli concreti.
  • Probabilmente viola il OCP - ad esempio, immagina di avere un modulo log che scrive sul file system (attraverso il modulo fs ). Se voglio estendere questo modulo di log per inviarlo alla rete, sarebbe molto difficile.

* Questo potrebbe funzionare con CommonJS o anche con i moduli AMD poiché sono implementati principalmente nella user-land. Tuttavia, non sono sicuro di come ciò sia possibile con la sintassi ES6% diimport.

Iniezione di dipendenza

Utilizzando l'iniezione di dipendenza, sarebbe più simile a:

module.exports = function doSomethingWithRequest(someModule) {
  // do stuff
  someModule.someFunc()
  // do other stuff
}

vantaggi

  • Maggiore testabilità: ora è più semplice eseguire lo stub / mock someModule , anche usando la sintassi ES6.
  • È possibile onorare il DIP: non necessariamente però, poiché il modulo client può ancora essere programmato per l'implementazione e non un'interfaccia.

Svantaggi

  • Incapsulamento rotto: la domanda principale che rimane è:

    Ok, then who will create/require the dependencies?

  • Farlo in ogni client del modulo sembra molto WET .
  • Probabilmente mi richiederebbe l'utilizzo di un contenitore DI per essere fattibile in un progetto reale.

Quindi, la vera domanda qui è:

Why Javascript developers tend to lean towards the first approach?

Questo è solo "il modo Javascript"?

Io stesso scrivo codice come questo la maggior parte del tempo. Ho avuto la mia giusta parte di setup di test usando le librerie di simulazione, ma mi è sempre sembrato sbagliato farlo.

Mi manca qualcosa?

    
posta Henrique Barcelos 24.11.2016 - 14:14
fonte

1 risposta

5

Sono principalmente un programmatore PHP, ma sono stato in contatto con 4 team JavaScript da circa un anno.

Come programmatore orientato agli oggetti il principio dell'iniezione di dipendenza sembrerebbe il modo migliore, tuttavia mi è stato detto diversamente da pochi sviluppatori JS. JS è un mondo completamente diverso.

Poiché JavaScript ti permette di eseguire il patch su qualsiasi cosa e tutto utilizzando tecniche molto semplici, gli sviluppatori di JavaScript hanno imparato ad adattare una tecnologia diversa su come costruire applicazioni JavaScript su larga scala. Molti di questi sono costruiti come insiemi di moduli autonomi, che espongono la funzionalità attraverso le esportazioni pubbliche, nascondendo gli interni del modulo in modo da non consentire ad altri di riscrivere le funzioni su cui si basa.

Di solito il solito approccio è persino di non esporre un costruttore come mai, ma piuttosto di esporre la costruzione di un oggetto usando un factory wrapper - per la stessa identica ragione: se offri a qualcuno l'accesso a un oggetto, possono istanziare direttamente è permesso loro di cambiare qualsiasi cosa.

Sfruttando il design modulare, neghi agli altri di maneggiare le tue funzioni che ti aspetti di lavorare, ma hai comunque la possibilità di testare i tuoi moduli - tramite l'API pubblica del file richiesto, l'API che hai creato.

    
risposta data 27.11.2016 - 17:57
fonte

Leggi altre domande sui tag