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, Object> SINGLETONS =
new HashMap, Object>();

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]