Using Singleton Pattern in Java

Singleton is probably one of the most used design pattern. It is easy to implement and really useful. It is used when only one instance of a class is needed.

In the following example I will write a logger class for a bank. It should register all the withdraws, deposits and transfers in a single file.

public class Logger {
    private final String logFile = “demo_log.txt”;
private PrintWriter writer;
    private Logger() {
try {
FileWriter fw = new FileWriter(logFile);
writer = new PrintWriter(fw, true);
} catch (IOException e) {}
}
    public void logWithdraw (String account, double amount) {
writer.println(“WITHDRAW (“
+ account + “): “ + amount + “$”);
}
    public void logDeposit (String account, double amount) {
writer.println(“DEPOSIT (“
+ account + “): “ + amount + “$”);
}
    public void logTransfer (String fromAccount, String toAccount, double amount) {
writer.println(“TRANSFER (“
+ fromAccount + “->” + toAccount + “): “ + amount + “$”);
}
}

After testing it I realise that when I use more than one logger my log file is total chaos. By creating more than one instance all my loggers conflict within each other. The solution is really simple. We need the singleton pattern.

Step 1: Add a static attribute

In order to avoid the creation of more than one instance we must add an static attribute of the same class and initialise it to null.

private static Logger logger = null;

Step 2: Write a getInstance method

In order to get our only instance we need to write a special method. This method should be static, have no input parameters and return an object of the same class. If our static attribute is equals null, we should initialise it with a constructor. Otherwise we don’t have to do anything.

public static synchronized Logger getInstance(){
if(logger == null)
logger = new Logger();
return logger;
}

Step 3: Use it!

In order to use our logger we don’t do it calling it’s constructor. Instead we call the getInstance() method. This way there will be only one instance of this class.

Logger logger1 = Logger.getInstance();
Logger logger2 = Logger.getInstance();
Logger logger3 = Logger.getInstance();
logger1.logDeposit(“0001”, 80.5);
logger2.logWithdraw(“0002”, 100);
logger1.logTransfer(“0001”, “0003”, 40);
logger3.logDeposit(“0004”, 56.74);
logger2.logWithdraw(“0005”, 30);

Here is a comparison between a log file from a logger with and without the singleton pattern:

  • Without Singleton:
DEPOSIT (0004): 56.74$
RWITHDRAW (0005): 30.0$
.0$
  • With Singleton:
DEPOSIT (0001): 80.5$
WITHDRAW (0002): 100.0$
TRANSFER (0001->0003): 40.0$
DEPOSIT (0004): 56.74$
WITHDRAW (0005): 30.0$

You can get the example code from my GitHub account: https://github.com/paguos/designpatterns