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.
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.
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.
What if my class has only private fields which injected by the container? Is it good or bad? In that case, I have to use DI framework in testing (and maybe that's not bad) but on the other hand, no setters, no unnecessary code. Is that bad practice or not?
Setter methods are way of achieving abstraction which is one the most important principle of OOP. Ideally the code should not be dependent on container. I think setter methods will provide standard way of using DI and in addition good code readability. I always consider setter DI a good practice unless my class instantiation is dependent on some other dependency (for which i will use constructor based DI).
I think you should not depend on container for performing DI.
Hope this helps.
strong text**First, what are the alternatives to DI via setter methods? Martin Fowler distinguishes three ways: **interface, setter and constructor injection. So none of these ways is good or bad by definition, it's how you use them and what suits your system best. If you want your fields immutable during after object creation, use constructor injection with private fields.
Nonetheless Setter injection is the most common way of DI and several frameworks rely on it. If you're unsure go with this way. You'll also find lots of information about it.
If your question targets the use of setters at all, the question is if your class is a data structure (see Martin's Clean Code ch. 6 for detailed information). In other words, if your class has no other purpose than holding some data and you can make your fields public(*). If it holds business logic, use private fields and getters/setters.
(*) personally I disagree with that, but that's only me. :-)
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'm developing plugins in Eclipse which mandates the use of singleton pattern for the Plugin class in order to access the runtime plugin. The class holds references to objects such as Configuration and Resources.
In Eclipse 3.0 plug-in runtime objects
are not globally managed and so are
not generically accessible. Rather,
each plug-in is free to declare API
which exposes the plug-in runtime
object (e.g., MyPlugin.getInstance()
In order for the other components of my system to access these objects, I have to do the following:
MyPlugin.getInstance().getConfig().getValue(MyPlugin.CONFIGKEY_SOMEPARAMETER);
, which is overly verbose IMO.
Since MyPlugin provides global access, wouldn't it be easier for me to just provide global access to the objects it manages as well?
MyConfig.getValue(MyPlugin.CONFIGKEY_SOMEPARAMETER);
Any thoughts?
(I'm actually asking because I was reading about the whole "Global variable access and singletons are evil" debates)
Any thoughts?
Yes, for the current use-case you are examining, you could marginally simplify your example code by using statics.
But think of the potential disadvantages of using statics:
What if in a future version of Eclipse Plugin objects are globally managed?
What if you want to reuse your configuration classes in a related Plugin?
What if you want to use a mock version of your configuration class for unit testing?
Also, you can make the code less verbose by refactoring; e.g.
... = MyPlugin.getInstance().getConfig().getValue(MyPlugin.CONFIGKEY_P1);
... = MyPlugin.getInstance().getConfig().getValue(MyPlugin.CONFIGKEY_P2);
becomes
MyConfig config = MyPlugin.getInstance().getConfig();
... = config.getValue(MyPlugin.CONFIGKEY_P1);
... = config.getValue(MyPlugin.CONFIGKEY_P2);
You suggest that
MyPlugin.getInstance().getConfig().getValue(MyPlugin.CONFIGKEY_SOMEPARAMETER);
is too verbose and
MyConfig.getValue(MyPlugin.CONFIGKEY_SOMEPARAMETER);
might be better. By that logic, wouldn't:
getMyConfigValue(MyPlugin.CONFIGKEY_SOMEPARAMETER):
be better yet (Maybe not shorter, but simpler)? I'm suggesting you write a local helper method.
This gives you the advantage of readability without bypassing concepts that were crafted by people who have been through the effort of fixing code that was done the easy/short/simple way.
Generally globals are pretty nasty in any situation. Singletons are also an iffy concept, but they beat the hell out of public statics in a class.
Consider how you will mock out such a class. Mocking out public statics is amazingly annoying. Mocking out singletons is hard (You have to override your getter in every method that uses it). Dependency Injection is the next level, but it can be a touch call between DI and a few simple singletons.