Singleton pattern is one of many design patterns used widely in software engineering. It is used to restrict instantiation of a class to only one object. In this article, I will introduce singleton usage in JAVA-like programming languages with object oriented approach and show bright examples of its implementation.
In following text I will refer to singleton as to class based on singleton design pattern.
Singleton is class that you want to use in server based applications or for implementing other design patterns (e.g. facade pattern). Why would you want that? Because singleton is used to manage coordination or resource sharing from one place of application. Some may say that it is an excuse for static global access. Well, kinda yes, but to fight back, it's better because it doesn't consume that much resources and applies piece of logic and security right there. And especially in places where you need global central access with implemented interface, singleton will be your choice.
Let's jump to basic implementation. We implement singleton as a class, that contains method for retrieving reference to singleton object. If singleton doesn't exist, it is created first. To ensure existence of only one singleton in particular virtual machine at time, we will set constructor of this class to protected (occasionally private, if you don't plan any inheritance actions later). Example given:
public class MySingletonClass { /** * Don't forget to protect your constructor from misuse */ protected MySingletonClass() { } static private MySingletonClass instance; public static MySingletonClass getInstance() { if (instance == null) { instance = new MySingletonClass(); } return instance; } }This basic example it's just an outline on how things should be started and I recommend using more complex implementation called volatile double check locking. It is synchronized as well, what is crucial in concurrence programming. Unfortunately, because of known issues in older JAVA versions it can be only used from version 1.5 and higher. Example snippet:
public class MyVolatileSingletonClass { private static volatile MyVolatileSingletonClass instance; /** * Protect again */ protected MyVolatileSingletonClass() { } public static MyVolatileSingletonClass getInstance() { if (instance == null) { synchronized (MyVolatileSingletonClass.class) { if (instance == null) { instance = new MyVolatileSingletonClass(); } } } return instance; } }If you don't work with JAVA 1.5 or higher, try following this outline:
public class MySynchronizedSingletonClass { private static MySynchronizedSingletonClass instance; /** * Protect again */ protected MySynchronizedSingletonClass() { } synchronized public static MySynchronizedSingletonClass getInstance() { if (instance == null) { instance = new MySynchronizedSingletonClass(); } return instance; } }Second example tends to slower performance because of whole method synchronization but both of these outlines are helpful in multi-threaded applications. For people who are newbies and are missing the point I just point out that these are design patterns examples, not hard coded classes. You can put other class variables inside and also rename the class :-). You should use encapsulating approach and private modifiers where possible as it is one aspect of the object oriented programming. Let's see how it works:
public class MySingletonClass { private static MySingletonClass instance; private String name; private boolean human; /** * Protect again */ protected MySingletonClass() { } public static MySingletonClass getInstance() { if (instance == null) { instance = new MySingletonClass(); } return instance; } /** * This method is called getter as it return you value of instance variable * @return Value of name */ public String getName() { return name; } /** * This method is called setter as it sets wanted value to instance variable * @param name Value you want to assign to this variable */ public void setName(String name) { this.name = name; } /** * By convention, getters for boolean variables are marked by "is" prefix * as you ask for true or false * @return Value of boolean */ public boolean isHuman() { return human; } /** * And another setter, this time for boolean variable * @param human Boolean that you set to this instance variable */ public void setHuman(boolean human) { this.human = human; } }Beware of synchronizing getters and setters in concurrence programming. You have to watch if they are going to be accessed by multiple threads.
I hope you found this article useful and that you understood this design pattern. Please, leave your feedback in comments below, thank you.