Continue reading “Beyond Java” by Bruce Tate I came across this subject (dependency injection) and decided to provide some excerpt of it here on this blog.
This is really helpful technique for unit testing when you need to substitute actual business object with a mock. But it also ingests additional level of complexity into your application. Everything has a cost.

The difference dependency injection in Java and Ruby is a little tougher to understand for Java developers. In Java, dependency injection is rapidly changing the way that we build applications. It’s a relatively simple concept:

class Speaker {
	void speak(String words) {
		System.out.println(words);
	}
}
class Consumer {
	Speaker mySpeaker;
	void saySomething() {
		mySpeaker.speak("something");
	}
}

Notice Consumer. It doesn’t instantiate Speaker. That job goes to a third party. We’ll call it Container:

class Container {
	public static void main(String[] args) {
		Speaker speaker = new Speaker();
		Consumer consumer = new Consumer();
		consumer.mySpeaker = speaker;
		consumer.saySomething();
	}
}

You can make some simple improvements. You can encapsulate mySpeaker with a getter and setter. You can then extract an interface called Speaker, and provide implementations for FrenchSpeaker, EnglishSpeaker, and SpanishSpeaker. You can also make a configuration file, in Java or XML, describing all the objects that you want to treat this way.

You’d then have most of what you’d need for a basic dependency injection container: configuration, third-party life cycle control, and the ability to loosen the coupling between Speaker and Consumer. With a dependency injection container, you could change implementations of Speaker without changing any code in any of the consumers. You could also inject a test implementation of Speaker without impacting the base code, a critical technique in Java for test-first development. You’d also have a consistent strategy for configuration.

Advertisements