Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Not All Singletons Are Evil

DZone's Guide to

Not All Singletons Are Evil

· Java Zone
Free Resource

Microservices! They are everywhere, or at least, the term is. When should you use a microservice architecture? What factors should be considered when making that decision? Do the benefits outweigh the costs? Why is everyone so excited about them, anyway?  Brought to you in partnership with IBM.

Among all the object-oriented design patterns, I think Singleton has the worst reputation. They have been called “evil,” “liars” and even “stupid,” and for good reasons:

  • singletons are global access points, making client APIs hide their dependencies on them
  • singletons make testing harder, mainly because they are hard to mock and inject

This is true, but only when Singletons are implemented and used in the “traditional” way:

  1. Singletons cannot be extended (note that the class is final and the constructor is private)

    public final class MySingleton {

    private static final MySingleton INSTANCE = new MySingleton();

    public static MySingleton instance() {
    return INSTANCE;
    }

    private MySingleton() {}

    public void doSomething() {
    // something here
    }
    }
  2. Singletons are called anywhere in your code
    public void someMethod() {
    MySingleton.instance().doSomething();
    // keep doing stuff
    }

Nothing is completely evil

Just like everything else, nothing is completely good or bad. I’ve been using Singletons in the next version of FEST-Assert in a way that avoids the problems mentioned earlier:

  1. Do not make the Singleton final, making creation of mocks from a Singleton possible (BTW, Mockito can mock non-final classes with private constructors.)
  2. Have the Singleton’s constructor package-protected. This is handy if your Singleton depends on other classes that need to be mocked during testing of the Singleton. This way, in your test, you can change the state of a new instance of the Singleton, without changing static state (that is, the state of the Singleton instance of a class.)
  3. Inject Singletons just like any other dependency, completely avoiding the “global access point” problem.

Sounds good. Show me the code!

The following code is similar to what we have done in FEST, but a lot shorter and simpler. You can also take a look at the code in the github repository.

Here is the Singleton:

public class MySingleton {

private static final MySingleton INSTANCE = new MySingleton();

public static MySingleton instance() {
return INSTANCE;
}

@VisibleForTesting MySingleton() {}

public void doSomething() {
// something here
}
}

 Currently, I’m doing manual dependency injection, because I consider the project to be pretty small and I’m trying to keep external dependencies to a minimum. Of course, you can (and probably should) use Google Guice :)

public class SomeClient {

@VisibleForTesting final MySingleton mySingleton;

public SomeClient() {
this(MySingleton.instance());
}

@VisibleForTesting SomeClient(MySingleton mySingleton) {
this.mySingleton = mySingleton;
}
}

 As you may guessed by now, the constructor SomeClient(MySingleton) is used in tests, passing a mock MySingleton (and of course I also test that the default constructor uses the Singleton instance.) Any non-test code just calls the default constructor SomeClient().

Conclusion

Despite the bad reputation that Singletons have, they can still be pretty useful. As long as Singletons are:

  1. extensible
  2. injected, and
  3. do not have static mutable state (state by itself is not bad)

they are as good as any other tool.

From http://alexruiz.developerblogs.com/?p=1832

Discover how the Watson team is further developing SDKs in Java, Node.js, Python, iOS, and Android to access these services and make programming easy. Brought to you in partnership with IBM.

Topics:

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}