开发者

Dependency Injection: What's wrong with good old-fashioned refactoring?

D开发者_高级运维I creates an extra layer of abstraction so that if your implementation class ever changes you can simply plug in a different class with the same interface.

But why not simply refactor when you want to use a different implementation class? Other languages like Python and Ruby work fine this way. Why not Java?


That is an incorrect characterization of dependency injection. It is not that you have one implementation of a particular interface that changes over time; rather, it is possible that there will be many different implementations of an interface all at once, and which implementation will be used can vary over multiple different runs of the program. For example, in your actual program, you might want to use one implementation, while during unit testing, you might want to "mock out" that implementation with an alternative version that is easier to test. In this case, refactoring is not a solution, because you need to be able to test all the time without interrupting the rest of the development process.

It should also be noted that dependency injection is usually used as a solution to the Singleton anti-pattern; it allows one to have a singleton object that can be easily mocked out during testing. And, if later it turns out that the singleton assumption really is incorrect, that singleton can be replaced with various implementations.

Some resources which you may find helpful in better understanding the topic:

  • Java on Guice: Dependency Injection the Java Way
  • Big Modular Java with Google Guice
  • Singletons are Pathological Liars
  • Why Singletons are Evil
  • Root Cause of Singletons
  • Dependency Injection Myth: Reference Passing


So you are saying Python and Ruby can't have dependency injection? Or Java can't work fine without DI?

Besides you've missed the one of the most characteristic of DI, that you can have Dynamic DI, not just at compile time, but at run time. In Software Engineering there is always a question of is there too much Abstraction and too little and it really comes down to how you design a solution to your problem


Not quite. The issue here is that when you write a code snippet like:

Runnable r = new MyFooRunnable();

you essentially decide that the Runnable you will need is a MyFooRunnable (and not a MyBarRunnable or a third one). Occasionally you will want to postpone that decision from compile time to deployment time, so that the deployer can decide how the individual modules your application consists of are to be glued together.

Traditionally this has been done with factories, but this just moves the actual decision around in code and you still have to know all the possibilities when coding the factory or let it read instructions from a configuration file (which tends to be fragile to refactoring).

Dependency Injection is a formalization of configured factories in a way so the code does not need to know hardly anything about how things work. This is also why annotations have been found so useful for pointing out where the Dependency Injection should happen. If running the code in a non-DI setting (like a junit test) then there does not happen anything (which would have been hard to do with Factories littered all over).

So, Dependency Injection used liberally allows you to write modules that "snap" well together without knowing of each other at compile time. This is very similar to the jar-file concept, but it has taken longer to mature.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜