Advantages & Disadvantages of Dependency-Injecting Non-Instantiable Objects
What, in your opinion, are the advantages and disadvantages of dependency-injecting non-instantiable objects in J开发者_StackOverflowavaScript?
Some context you may want to explore are:
- Unit-testing
- Is it worth dep-injecting it? After all, you can overwrite the non-instantiable "static" dependency to a fake object for each test even without dep-injection.
- Refactoring
- Will it become more difficult to locate & refactor the non-instantiable dependency?
- Readability
- Which implementation is easier to follow? Is the implicitness or explicitness important to you?
- File-size
Code
Non-instantiable object:
WindowFactory = {
buildWindow: function() {
return {};
}
};
Dependency-Injected:
(House = function(windowFactory) {
this.windowFactory = windowFactory;
}).prototype = {
build: function() {
var window = this.windowFactory.buildWindow();
}
};
var house = new House(WindowFactory);
vs. The Non-Dependency-Injected variant:
(House = function() {
}).prototype = {
build: function() {
var window = WindowFactory.buildWindow();
}
};
var house = new House();
Context
My primary goal is to make the code above testable. I've gotten into a
habit of externalizing instantiable dependencies (e.g var window = new
Window(); var house = new House(window);
). This helps when unit-
testing instantiable objects (e.g. House
), since instead of the real
dependencies (Window
) I can instantiate the object with a fake (var
fakeWindow = {}; var house = new House(fakeWindow);
), and not have to
worry about redundantly testing the dependencies while testing my
object. (This form of dependency-injection is also useful when testing
objects that depend on some data being retrieved via XHR, DOM-events,
sessionStorage, or cookie.)
Now, when the dependency is an instantiable object itself, the benefits are clear to me; but when the dependency is a non- instantiable object (e.g. WindowFactory in the code above), I have second thoughts about the usefulness.
If you get some gain in unit-testing, that might be more than enough for me. You'll be able to cleanly test the functionality without depending on global/external state. The added bonus then becomes the readability; you clearly show which global state/api you depend on in the arguments of your function.
Being able to change the static methods in the setup/teardown of the tests is a workaround for the problem, but I personally find it to be error-prone and a chore doing it.
精彩评论