views:

834

answers:

2

Are there (performance) penalties* associated with the Enum Singleton Pattern in any way, as it seems to be used less than the classical singleton pattern or the inner holder class idiom?

* Penalties, such as the cost of serializability in cases when it is not needed and such, or is the usage low because few of the developers read Effective Java 2nd edition?

+4  A: 

All Java singleton patterns (both this and the standard with private constructor and static accessor) have this bad property that if you to test them (or test anything that even remotely depends on them) can use this and only this object.

For example if you want to test PrintingService class that depends on PrintingSingleton you will not be able to replace this printing singleton with a mock because it is bound statically.

i.e. imagine testing this function

boolean printDocument(Document d) {
  if (PrintingSingleton.INSTANCE.isPrinterEnabled()) {
    PrintingSingleton.INSTANCE.print(d);
  }
  throw new RuntimeExeption("Printing not enabled");
}

with a test

@Test(expectedExceptions = {RuntimeException.class})
public void testPrinting() {
  PrintingService service = ...
  service.print(new Document());  // How will you simulate 
                                  // throwing an exception?
}

Personally, I would just avoid using singletons that way but rather introduce dependency injection, via Guice, Spring or Pico Container. That way you ensure existence of only one object, while not limiting yourself to not being able to mock the object out for example for tests.

Marcin
you could test the singleton instead of the wrapper that uses it?
Chii
+1 valid point, still the solution to this is already in EJ2. Use an operation interface and you can have the enum and mock implement that.
kd304
@kd304: you'd need to pass then this enum singleton around in every place where you'd want to use it. In such situation you don't really have that much advantage of its singletonness and you're just better off by having Guice/Spring/Pico ensure that for you.
Marcin
Thanks, especially for the dependency injection samples.
kd304
+1  A: 

You will not get any performance penalties for using an Enum-based singleton, as Enums are really just regular classes at runtime. I suppose you may get a very slight performance hit at classload time since the system may be doing all the correct initialization that are needed for correctness. There should be no cost to being Serializable, since that is just a tag interface, only check if you try to serialize. It really is the best known method for creating singletons!

Adam Goode