MyObject object = new MyOject(new Dependency());
class MyOject() {
private Dependency dependency;
MyObject(Dependency dependency) {
this.dependency = dependency;
}
}
is better than this
MyObject object = new MyOject();
class MyOject() {
private Dependency dependency;
MyObject() {
this.dependency = new Dependency();
}
}
because of some reasons. The most important reason is, that the second example doesn't support different implementations for the dependency. Imagine you want to do tests and mock a heavy database connection. Using interfaces in those situations and an injected implementation is recommended. Second, if you change something on the dependency class, you have to touch the intrinsics of the object class, which doesn't sound right, because you don't want to touch this class.
After it's clear to use DI, one can go a step further. Instead of how our dependencies are solved, it would be nice to just say what dependencies we want to have: declerative programming. How they are solved is easy most of the time and handled later, even in a declerative manner.
So for Java SE applications, it's not trivial to chose the right framework for injection. For the platform standard CDI, an implementing library is needed. Other containers, like Google's Guava or Spring are rather heavyweight and provide a rich set of features. However, there's a new shooting star I dove into: Dagger. Promises to be simple and fast, because it's (optional) a compile time thing. And I can confirm that it's easy and nice.
For example how many times have you already used the Singleton pattern? With dagger, you can just annotate your class as a Singleton and the framework does everything else for you.
@Singleton
public class Config {
public int WIDTH = 1280;
public int HEIGHT = 720;
@Inject
public Config() {}
}
A small configuration for a renderer framework of mine. Can't get any simpler than this - only one odd @Inject constructor annotation I don't understand completely. To obtain the service, you declare the injection in the consuming class. For example a context class of the application.
@Singleton
public class Context {
@Inject Config config;
}
The context class is not meant to provide access to the configuration. The configuration can be injected directly into all other classes as well.There is a ton of other features and having some objets wired together automatically is great. But I already found a job that Dagger can not fullfill - something that is called assisted injection. The factory - for example for your game objects - can be injected into the context. You can inject something like a provider as well; this is an object that works like a factory but cannot take your parameters to construct them. While other frameworks may be used for injection of objets with partially managed fields, Dagger can't do it, maye can do it in the future.
Keine Kommentare:
Kommentar veröffentlichen