There's a nice tutorial that seems to make sense about DI and IoC
Wouldn't it be easier to make the getCustomer methods static in the injector classes? I don't really see any reason to instantiate injector objects in this case.
So instead of:
MessageServiceInjector injector = null;
Consumer app = null;
injector = new EmailServiceInjector();
app = injector.getConsumer();
app.processMessages(msg, email);
We would just do:
Consumer app = null;
app = EmailServiceInjector.getConsumer();
app.processMessages(msg, email);
How to write injector classes properly? At the end of the article it says
We can achieve IoC through Factory Pattern, Template Method Design
Pattern, Strategy Pattern and Service Locator pattern too
but I guess none of the patterns was used in this example (IoC in this case is just simplistic). So how would it be done in a real project (assuming no external frameworks or IoC containers are used), i.e. if I wanted to create all the necessary stuff to let me use DI in my code.
"Easier"? I don't think it makes any difference to your DI engine.
Static would assume one instance. What if you want an instance per request, as you might for each web request? Static won't do then.
I've used Spring for more than ten years. It has a bean factory and DI capability that can deal with singleton or per request instances. Have a look at how it works to see one successful way to do it.
I think Martin Fowler's DI article, now 11 years old, still explains it well.
In real world project, you should use Dependency injection framework like Spring Framework. The are other as well likeGoogle Guice.
I have been personally using spring for couple of years now and it has grow to much larger extent apart from basic DI.
Wouldn't it be easier to make the getCustomer methods static in the injector classes?
It seems to me that what this article is calling an Injector is actually an abstract factory. We use abstract factories when we want a class to create objects at a later point it time.
In general it is not recommended to have static methods. Mainly because the classes that call the static method will have a hard dependency on it, i.e., you cannot at a later point in time consume a different dependency without changing the consuming class code. And this is exactly the problem that DI is trying to solve.
Another reason is that it is hard to mock static methods in a unit test.
So how would it be done in a real project?
In real projects you should construct your objects (e.g. services) in the composition root.
There are two ways to do it. Either use a DI container, or use Pure DI.
In my opinion, Pure DI is a better choice. See this article for a reason why.
Related
Introduction
I'm using Dagger 2 for a project that's modeled using the principles of DDD.
I'd like to use the Builder Pattern to create complex entities and the way I'd normally get an instance of the builder was by using a static factory method: ComplexEntity.builder().
Aggregate roots will get strongly typed IDs, i.e. ComplexEntityID, that require a value generator for new instances. Right now I have a method for that in my module: #Provides ComplexEntityID provideComplexEntityID(IdValueGenerator generator) { return new ComplexEntityID(generator.nextId(); }.
ComplexEntityBuilder needs an instance (or provider) of ComplexEntityID in order to create a ComplexEntity. But static injection is recommended against by the people from Guice and Dagger (among others) for good reasons.
Question
How to create instances of ComplexEntity using a builder, without using static injection? In other words, how to get an instance of the builder?
Sticking to ComplexEntity.builder() would be nice because it's a common convention, but I'd think that the only way to make an instance available in a static method without using the new () keyword is by using static injection.
Another approach I could think of is to also create ComplexEntityFactory and put the builder() method there. But it seems a bit strange to use a factory and a builder together:
Inject a factory in the class where you need it
complexEntityFactory.builder().value1(...)
.value2(...)
.build();
What would be the recommended approach in this case?
Edit: If it turns out to a dedicated factory after all, tt would be nice if this factory could still be generated using AutoFactory or something similar
I think there is a more elegant solution than the one proposed by jaco0646 in the comment:
Builders are a special kind of service: You use them to realize a specific goal, but they don't have a life cycle or meaning within the domain.
So just inject builders as you would any other service.
This has several advantages:
Builders can use other services and factories by depending on them. In your case this is the dependency on the factory of ComplexEntityID.
Having a dependency on a builder is explicit (which is a good thing). At the moment, your dependency is hidden in a call to a static method.
You can replace the builder in tests.
Overall, this approach improves cohesion and reduces coupling.
One potential pitfall to be aware of is that builders usually have internal state (unlike typical services). So make sure to configure your dependency injection container such that a new builder instance is created for every resolve request.
What's wrong with following code?
public class DeDoper {
public boolean wackapediaOkToday() {
DnsResolver resolver = ResolverFactory.getInstance().makeResolver();
return resolver.getIpAddressFor("wackapedia.org").equals("123.456.78.9");
}
}
Why is this version preferred?
public class DeDoper {
#InjectService
private DnsResolver resolver;
public boolean wackapediaOkToday() {
return resolver.getIpAddressFor("wackapedia.org").equals("123.456.78.9");
}
}
I can easily mock ResolverFactory.makeResolver() and this is the same as setting resolver is latest example.
This is what was said in this article from ProQuest.biz:
This [first] version of WackapediaOkToday is, very loosely speaking, "injected" with a DnsResolver (although it's admittedly less like getting a shot, and more like asking a waiter for the check). But it does solve the testing problem, and the "turtles all the way down" problem.
Chained to the Factory
But in this [first version] approach, we are literally "chained" to the Factory classes. (Worse, if the objects created by our Factories have dependencies in turn, we may have to introduce new Factories inside our Factories.) We haven't fully "inverted" our control, we're still calling (controlling) the Factories from inside our classes.
What was needed was a way to get rid of the control in our classes entirely, and have them told what they were getting (for their dependencies).
Let's say you had a service which can have multiple implementations, like "FileLocator". This has a FilesystemFileLocator, which takes as an argument the path to the root of the files and a S3FileLocator, which takes as an argument your S3 credentials. The former would require you to write a service locator to figure out which version you want and then return it. That code, in turn, has to go get your data, build the appropriate type of file locator, etc. You're doing what the IOC container should do for you. On top of that, you've inject a dependency on that specific creation method.
In the second version you've defined (through annotations or XML) what type of file locator you want. The IOC container instantiates and manages that for you. It's less code you have to maintain. It's also less work if you want to introduce a third type of FileLocator. Or maybe you refactor your code so file locators are singletons, or if they were singletons they're now factories for fresh locators, or maybe you want to pool locator instances. In all these cases there will be less breakage if you work with your IOC container.
I've always known Singletons to be "bad", but only now that I've made the move to Java from C++ have I decided to find a way around them. From a bit of reading, I've found that either Factories or Dependency Injection could possibly do the job, but I'd like some confirmation on this.
As an example, I was about to write a AnimationCache singleton that would store a Map<String, Animation>. Different classes should be able to have access to this class (basically) anywhere so that they can easily and efficiently load Animations. A very brief example of what the equivalent code would look like using DI would be great.
Also, is Guice a good framework for DI with non-web apps? I have used Spring for web development, but I'm not so sure that'd work for games.
Spring and Guice will do fine. I personnally prefer Guice for pure dependency injection, but Spring offers much more.
The code would just look like this:
public class AnimationCacheClient {
private AnimationCache cache;
#Autowired // for Spring, or
#Inject // for Guice (but I think Spring also supports it now)
public AnimationCacheClient(AnimationCache cache) {
this.cache = cache;
}
// ...
}
I personnally prefer constructor injection, but you might also use setter injection or field injection.
Note that the purpose of DI is not to have "easy singletons", though. Its main purpose is to make the code (of AnimationCacheClient, here) easily unit-estable, by being able to inject mock dependencies (here, a mock AnimationCache instance).
Using Spring, DI is very simple. Using the #Autowired annotation, you don't even need additional xml to wire things up or a setter method. A member in the class that needs access to the one that has been your singleton before will do.
Here is a good example: http://www.developer.com/java/other/article.php/3756831/Java-Tip-Simplify-Spring-Apps-with-Autowired.htm
I recently 'withnessed' this thread on Singleton and how bad it might be (or not) and what you can do to bypass it. Well worth the read.
I have been reading Effective Java and I have some concerns regarding the first Item "use
static factory method instead of constructor" in relation to TDD and dependency injection.
The item says that you should avoid having public/protected/default constructor and expose
it using static factory. I agree with all the advantages related to using static factories
like factories can have name, you can return subtype, you can reduce verbosity etc. But, I
think in disadvantages Joshua missed TDD because having static factories in your code will
lead to tight coupling and you can't mock the class using it. We will not be able to mock
the class which will be having static factories. So, it hampers test driven development.
Second point, I think he missed that in todays enterprise development most of the
applications use one or another dependency injection container. So, when we can inject
dependencies using DI so why should I use it.
Please explain how it applies to today's Java enterprise development which includes DI and
TDD.
The DI engine is the factory.
Joshua Bloch understands DI well enough. I think this is an artifact of history, because DI's ascent came after the first edition of "Effective Java".
"Effective Java" was published in 2001. Martin Fowler coined the term in 2004. Spring's 1.0 release came in March 2004.
Joshua Bloch didn't modify that chapter for the second edition.
The point is the coupling that "new" introduces. Anyone who understands that and factories will easily make the leap to DI engines. The point is that his statements regarding "new", and the remedy of using factories, is still true.
I see 2 separate issues here :
static factories vs using new()
dependency injection
When using new your code is just as tightly coupled as using a static method, actually even worse since the static factory can do some magic and return some specific implementation as long as it is a subclass or implementation of an interface.
With dependency injection the principle is also called the Hollywood Principle : "Do not call us, we'll call you". So in that philosphy you should not call new() or the static factory in your code, but have an external thing do that for you, either the DI framework or the unit test. This has nothing to do with factories or the use of new, as that is done somewhere else.
In that case factories are better because you can inject a test factory under your control. With new this is not possible (without doing weird things to the classpath like hiding the implementation with dummy objects in the test classpath, which I do not recommend btw).
I had the same concern you have, and that's how I found your question.
You say:
because having static factories in your code will lead to tight
coupling and you can't mock the class using it
the book suggests that you should expose the constructor of your class with a static method (api design). It doesn't suggest that you "hardcode" the static call all over your application (api usage).
Suppose you are using Guice for DI, and your interface is called Connection, you could do:
bind(Connection.class).toInstance(Connections.makeASpecificConnection(params));
And then your usual #Inject Connection connection;
Of course this is if your connection is a Singleton. If it's not, you could inject an Abstract Factory with an implementation that creates instances calling the static method of your class, but this might be way overkill and you'd be better using Guice alone.
Remember that this book is not targeted primarily at building huge enterprise applications, although its still very helpful.
Quote from the preface of the book:
While this book is not targeted solely at developers of reusable
components, it is inevitably colored by my experience writing such
components over the past two decades. I naturally think in terms of
exported APIs (Application Programming Interfaces), and I encourage
you to do likewise.
My application stores files, and you have the option of storing the files on your own server or using S3.
I defined an interface:
interface FileStorage {
}
Then I have 2 implementations, S3FileStorage and LocalFileStorage.
In the control panel, the administrator chooses which FileStorage method they want, and this value is stored in a SiteConfiguration object.
Since the FileStorage setting can be changed while the application is already running, would you still use spring's DI to do this?
Or would you just do this in your code:
FileStorage fs = null;
switch(siteConfig.FileStorageMethod)
case FileStorageMethod.S3:
fs = new S3FileStorage();
case FileStorageMethod.Local:
fs = new LocalFileStorage();
Which one makes more sense?
I believe you can use DI with spring during runtime, but I haven't read about it much at this point.
I would inject a factory, and let clients request the actual services from it at runtime. This will decouple your clients from the actual factory implementation, so you can have several factory implementations as well, for example, for testing.
You can also use some kind of a proxy object with several strategies behind it instead of the factory, but it can cause problems, if sequence of calls (like open, write, close for file storage) from one client cannot be served by different implementations.
I would still use Dependency Injection here. If it can be changed at runtime, you should inject it using setter injection, rather than constructor injection. The benefit of using any dependency injection is that you can easily add new implementations of the interface without changing the actual code.
DI without question. Or would you prefer to enhance your factory code when you create/update/delete an implementation? IMO, If you're programming to an interface, then you shouldn't bootstrap your implementations, however many layers deep it actually occurs.
Also, DI isn't synonymous to Spring, et al. It's as simple as containing a constructor with the abstracted interface as an argument, i.e. public FileApp(FileStorage fs) { }.
FYI, another possibility is a proxy.