I guess we have all heard about how bad static Singletons are and how Dependency Injection (DI) helps to make our application flexible beyond crazy. One common thing to do with DI is creating and using Singletons. I have been working a lot with DI frameworks in the past, mostly Spring and Google Guice. Although both do a great job, I have been wondering lately if my applications always need this great flexibility. Don’t forget using them comes with a lot of baggage, e.g. new third party dependencies or XML configuration files. In a big project this is probably not a problem, but in small projects it is just unnecessary. Note, I don’t state that Spring or Guice are bad, but sometimes the whole DI stack is just too much for small projects.
Singletons are a great example. They are simple to understand and to use. Like I mentioned, DI frameworks are often used to provide a “better” way to create Singletons, sometimes as their main purpose. I will present a simple , yet powerful enough, solution creating and instrumenting Singletons using a plain HashMap with no dependencies and configuration files.Why are Singleton considered bad? We all use them, we all need them. I think the problem is not using Singletons, it is to create them. We all have seen code like this:
[sourcecode language='java']public static final Application APPLICATION = new ApplicationImpl();[/sourcecode]
This code creates a Singleton of the interface Application. Through the public static modifier it is available for all other classes. Our problem solved! Not yet, where should we place this code? We could make Application an abstract class and place the static variable in it. But I don’t like this solution much. Why? Because a class should only do one thing. Application already has a purpose (some application related things), but creating a Singleton is clearly not Application’s job. Hence, we are creating a Singleton class that creates a Singleton for us. Instead of doing this with a public static variable we will provide a generic static method for it. Something like Singleton.get(???). Our get method needs a parameter to identify which class should be returned. We could create an enum Key, but then we also need to create a Key instance for every interface we want to register. A key already exists, the class of the interface. What about calling Singleton.get(Application.class)? That will do it. A HashMap then can hold the Singletons and get() returns the corresponding instance to the interface. Further, generics helps us to avoid casting.
Singleton.java
[sourcecode language='java']package com.hemju;
import java.util.HashMap;
public class Singleton {
private static final HashMap
new HashMap
static {
SINGLETONS.put(Application.class, new ApplicationImpl());
}
/**
* Returns a singleton which implements the given interface.
*
* @param
* the interface which is implemented
* @param clazz
* the class object of the interface
* @return a singleton instance of an implementing class or
* null when no implementation was found
*/
@SuppressWarnings(”unchecked”)
public static T get(Class clazz) {
return (T) SINGLETONS.get(clazz);
}
private Singleton() {
// make Singleton accessible only through static references
}
}[/sourcecode]
Done! We already can use our simple Singleton solution. Have a look at the example at the end of this text. I am still not 100% satisfied with the solution, but we are going in the right direction.
Open issues are:
- not really flexible
- no access control
- no exception management (casting null values)
- doesn’t work with Unit tests
I will address this issues in the next part of this series. If you think I missed any issues, just drop a comment and let me know.
Example:
[sourcecode language='java']package com.hemju;
public interface MyPrinter {
void print(String s);
}[/sourcecode]
[sourcecode language='java']package com.hemju;
public class MySoutPrinter implements MyPrinter {
@Override
public void print(String s) {
System.out.println(s);
}
}[/sourcecode]
[sourcecode language='java']package com.hemju;
public class MySerrPrinter implements MyPrinter {
@Override
public void print(String s) {
System.err.println(s);
}
}[/sourcecode]
[sourcecode language='java']package com.hemju;
public class Main {
public static void main(String[] args) {
// don’ forget to add
// SINGLETONS.put(MyPrinter.class, new MySoutPrinter());
// in the Singleton class
MyPrinter printer = Singleton.get(MyPrinter.class);
printer.print(”Hallo aus Linz”);
}
}[/sourcecode]

Klaus responded on 05 Oct 2008 at 8:14 pm #
When I read the first lines, your last concern of open issues immediately came up to me: lack of testing support.
In my recent project I’m currently using pureMVC (www.puremvc.org) that builds on a similar concept. Instead of your Singleton class you there have an ApplicationFacade that is accessible from (almost) everywhere in the your application.
Registration is not done via class or interface names but with a unqiue name (String) which I prefer because by just using the interface you are not able to register two implementations of the same interface.
The Multicore version of pureMVC even has the possibility to cluster your applicatino into multiple cores. That gives you the chance to not only have one big registry that knows everything but to have different cores. But as your main purpose are small applications, that won’t be too interesting for you.
Anyways, even if you’re just working on small applications, I’d really prefer the Spring way there as well. Why? Spring is non-intrusive, it doesn’t waste your code and if you’re just using the DI framework then you even don’t have any Spring code working at runtime. And if your project once grows you can benefit from all the features that Spring can provide.
And by using Spring (or Guice), you can avoid that big Singleton class that is aware of all implementations of your interface and also needs to do the job of dependency injection between your service objects…
heli responded on 05 Oct 2008 at 9:24 pm #
Hey Klaus,
thanks for stopping by and your comment. I know that the current “solution” isn’t really a good one, but my approach is to work from the “brutal” solution to a more elegant one. I think you will like the solution from part two more than this one.
Of course you are right when you say that Spring and Guice are the better choice for projects, even small ones. They are well designed, maintained, and also suited when the application grows. So why my approach? When download size matters. E.g. for applets or web start applications. The Guice built from Sep 09 has 939 KB and I guess Spring has even more. That’s a lot of baggage just for Singletons.
Btw. Haven’t had the time to check http://www.puremvc.org/ but I will.