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
orewire
. - 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?