In diesen Tagen tauchte eine Frage in meinem Kopf auf:
Widerspricht die Art und Weise, in der wir Javascript verwenden, fast allem, was in der traditionellen Softwareentwicklung als gute Praxis angesehen wird?
Ich habe eine Reihe von Fragen / Beobachtungen im Zusammenhang mit dieser Aussage, aber um das Format von StackExchange zu respektieren, ist es besser, wenn ich sie in verschiedene Fragen aufteile.
Modul erforderlich
Standard Javascript Code sieht heutzutage so aus:
const someModule = require('./someModule')
module.exports = function doSomethingWithRequest() {
// do stuff
someModule.someFunc()
// do other stuff
}
Vorteile
- Kapselung: Das Modul arbeitet eigenständig und weiß alles, was es zur Ausführung seiner Funktionen benötigt.
- Als Kolorist ist es für Kunden einfacher, das Modul zu verwenden.
Nachteile
- Schlechte Testbarkeit: Dies ist Standard, wenn DI nicht verwendet wird, aber in dynamischen Sprachen wie Javscript kann dies durch Module wie
mockery
oder umgangen werdenrewire
. - Es verstößt mit Sicherheit gegen das DIP - nicht zu verwechseln mit Dependency Injection. - da kann ich nur betonmodule importieren.
- Es verstößt wahrscheinlich gegen das OCP - stellen Sie sich zum Beispiel vor, dass ich ein Protokollmodul habe, das in das Dateisystem schreibt (über das
fs
Modul). Wenn ich dieses Protokollmodul erweitern möchte, um es an das Netzwerk zu senden, wäre es sehr schwierig.
* Dies funktioniert möglicherweise mit CommonJS- oder sogar AMD-Modulen, da diese hauptsächlich im User-Land implementiert sind. Ich bin mir jedoch nicht sicher, wie dies mit der ES6- import
Syntax möglich sein könnte .
Abhängigkeitsspritze
Bei Verwendung der Abhängigkeitsinjektion wäre dies eher wie folgt:
module.exports = function doSomethingWithRequest(someModule) {
// do stuff
someModule.someFunc()
// do other stuff
}
Vorteile
- Verbesserte Testbarkeit: Es ist jetzt
someModule
auch mit der ES6-Syntax einfacher, Stubs / Mocks durchzuführen. - Es ist möglich , das DIP zu würdigen: nicht unbedingt, da das Client-Modul weiterhin auf die Implementierung und nicht auf eine Schnittstelle programmiert werden kann.
Nachteile
- Gebrochene Kapselung: Die Hauptfrage lautet:
Ok, wer erstellt / benötigt dann die Abhängigkeiten?
- Dies in jedem Client des Moduls zu tun, scheint sehr WET zu sein .
- Dies würde wahrscheinlich erfordern, dass ich einen DI-Container verwende, um in einem realen Projekt realisierbar zu sein.
Die eigentliche Frage lautet also:
Warum neigen Javascript-Entwickler dazu, sich dem ersten Ansatz zuzuwenden?
Ist das nur "der Javascript-Weg"?
Ich selbst schreibe die meiste Zeit Code wie diesen. Ich hatte einen guten Teil des Testaufbaus mit spöttischen Bibliotheken, aber es fühlte sich immer irgendwie falsch an.
Vermisse ich etwas?