Design Patterns Uncovered: The Singleton Pattern
The next pattern in our series is the Singleton pattern. Singleton is probably the most infamous pattern, as it's use causes a divide in the development community- some say it belongs, others say it's against object-orientation.
Singletons in the Real World
In the real world singletons represent anything that is unique, so in theory, every person is a singleton. Putting things into a more concrete example, your house probably has just one central electical fuse box.
Design Patterns Refcard
For a great overview of the most popular design patterns, DZone's Design Patterns Refcard is the best place to start.
The Singleton PatternSingleton is known as a creational pattern - it's used to construct objects such that they can be decoupled from the implementing system. The
definition of Singleton provided in the original Gang of Four book on Design
Ensure a class has only one instance and provide a global point of access to it.
Across all 23 design patterns, the diagram definition of the Singleton pattern is the simplest:
We just provide one point of access to create an instance of the Singleton class. The constructor is kept private, giving the getInstance() method the responsibility of providing access to the Singleton.
This sequence diagram shows how simple it is for a client to get an instance of the Singleton.
Where Would I Use This Pattern?
When you need to ensure there's one instance of an object, available to a number of other classes, you may want to use the Singleton pattern. Singletons are used a lot where you need to provide a registry, or something like a thread pool. Logging is also another popular use of Singletons, providing one single access point to an applications log file.
So How Does It Work In Java?
This example will show how to put together the classic Singleton in Java, without thinking about the threading complications which we discuss later on in this article.
The Singleton class has some characteristics that we generally want to ensure two things:
- We lazily load our singleton based on the first request for access to it.
- There is no other way of instantiating our Singleton
Keeping this in mind, here is our Java representation of a Singleton.
public class Singleton
private Singleton instance;
public static Singleton getInstance()
instance = new Singleton();
We maintain the lazy loading principle here by only creating the instance when it is null, which will always be on the first call. Additionally, because we use a private constructor, we can only create the Singleton by calling the getInstance() method.
For completeness, here is how a client can access the Singleton:
//access the singleton
Singleton singleton = Singleton.getInstance();
//use the singleton
As you can see, it's fairly simple - but there are downsides.
Watch Out for the Downsides
As I mentioned at the beginning of this article, the Singleton is infamous in object oriented systems. A lot of the time the Singleton is used as a shortcut, so that the designer doesn't need to think properly about object visibility. If you're hacking in a Singleton so that there is global access to a resource, maybe it's not the right thing to do. It might be better to work out how to pass the reference to that resource around properly.
Another important consideration is multi-threading. If two threads call the getInstance() method at the same time, you can end up with two singletons. Making the getInstance() method synchronised solves this issue, but then you have the performance cost - calling a synchronised version of getInstance() will be slower than the non-synchronized version. However, maybe the best way around this is to sacrifice lazy-loading in the Singleton, ensuring there can only ever be on instance. A number of alternatives are listed here.
First, programs using global state are very difficult to test. ...the singleton user and the singleton become inextricably coupled together. It is no longer possible to test the user without also testing the singleton.
Second, programs that rely on global state hide their dependencies.
If you've been following this series you'll notice that no other pattern has had so many downsides and cautionary notes. It's true for all patterns that you need to carefully consider it's applicability to your problem before using it. With Singleton, consider it twice as much.
Other Articles in This Series
The Observer Pattern
The Adapter Pattern
The Facade Pattern
The Factory Method Pattern
The Abstract Factory Pattern
The Singleton Pattern
The Strategy Pattern
The Visitor Pattern
Later this week, we'll be taking a look at another creational pattern - the Factory pattern.