Feb 2, 2017

Singleton Pattern

Singleton

Single, as its name this pattern talks about one global references of a class during a process life cycle.
Table Of Content

Overview

For applying this pattern, the target class should hide(make it private) its constructor, so no any other object will create one. Then a static instance of the class is initialized by itself and make it accessible by a static method.

It's really easy to make a class single. Making the constructor private means no one will be able to make a(separated) instance, and simply the class itself creates one instance of itself and keeps it by a static field which is accessible by a public static method.
package wasys911992.blogger.java.pattern.singleton;
/**
 * by https://github.com/911992
 * arashmd.blogspot.com
 */
public class SingleGuy{
  //making the constructor private
  private SingleGuy(){
    System.out.print("Hello I'm a Single guy, Forever Alone!\n");
  }
  //create ONE instance of the class
  private static SingleGuy instance=new SingleGuy();
  //make the instance accessible for public
  public static SingleGuy getInstance(){return SingleGuy.instance;}
}

Usage

The question is "When do we need to use this pattern?" I have read some article about this, some devs say "Always use singleton whenever you need to limit instances from a class to one". While this definition is not wrong, but it doesn't mean we have to use singleton always(just like OOP is not really a wow thing!). For instance class Math would be singleton, it's true, but it's non sense.

I think we would have better definition Use Singleton pattern when there is one instance of one STATEFULL class is required. Yes I repeat when ONE STATEFULL object is required.

This is nonsense if Math class goes single!(why?) Because each method is completely independent of current object state(stateless). Suppose there is a class that provides methods for encryption/decryption, each method gets an array and returns an array, so because there is no any dependency(no such a shared field[state]) between methods and object, then using singleton approach is nonsense here(but possible). Please considering following samples.

Example (Don't)

Consider we have a Mathematical class, and we need to ensure only one instance of this class is allowed(required), then because this class is Stateless, then singleton pattern is not good idea here.
Bad Approach
Singleton pattern is not perfect for Stateless classes.
Or generally why thinking so much OO when something is completely functional?!

//not well-designed
class MyMath{
  //singleton guys usually have a state
  //or some fields shared belong to all threads
  private MyMath(){}
  //Please do not host functional things in OO way
  private static MyMath instance=new MyMath();
  public static MyMath getInstance(){return MyMath.instance;}
  private final long version=1990L;
  public long getVersion(){return this.version;}
  public double rectangleArea(double w,double h){
    return w*h;
  }
  public double diamondArea(double w,double h){
    return (w*h)/2;
  }
}

Good Approach
Use static members for Stateless classes instead of singleton pattern.

class MyMath{
  //Good approach, there is no need for singleton pattern because there is no state!
  //Generally becasue math stuufs are functional, not thinkink OO gives much sense
  private MyMath(){}
  public static final long version=1990L;
  public static double rectangleArea(double w,double h){
    return w*h;
  }
  public static double diamondArea(double w,double h){
    return (w*h)/2;
  }
}
Because class MyMath doesn't have any state, so methods are not required to get invoked by an instance and this is a good reason to prefer static members over singleton, in fact it makes our design better.

Initializing Modes

There are some solutions here for initializing a singleton instance, so does it important? and how should we initialize it?

Eager Mode

Initialize the instance with its declaration, use this mode when singleton load is not to huge or you are sure the instance will be used later.

as you see, this singleton guy creates initialize the instance reference by its declaration. I would say this is very simple and effective solution, even if you don't need the guy, JRE will not initialize(cannot promise) it of course when there is no dependency.
package wasys911992.blogger.java.pattern.singleton.initmode.eager;
/**
 * by https://github.com/911992
 * arashmd.blogspot.com
 */
public class EagerOne {
  private static EagerOne instance=new EagerOne();
  public static EagerOne getInstance(){return EagerOne.instance;}
private EagerOne(){
  System.out.println("Horray!, Eager One initialized");
}
}
//============================
public class UsingEager {

  public static void main(String[] args) {
    System.out.println("I'm going to use my eager singleton guy...");
    //JRE will not initialize the static members unless the very first class dependency
    EagerOne eo=EagerOne.getInstance();
    //using the guy
    //....
  }

}
Note: In Java, JRE will not initialize the singleton instance till the very first class dependency(hotspot looks like this, not sure about the other VMs).
But you could initialize the single instance just before the usage (for example at loading module process) via a static block.

Lazy Mode

This initialize mode is used when there is no need to use the class for each application start. The instance is initialized by the very first use (not class dependency).

As you see in above diagram, the instance is null by default, and this is getInstance() duty to initialize it. This is not a very hard work, but it makes the code a little curly. The instance will not be initialized till the first getInstance() method call.
package wasys911992.blogger.java.pattern.singleton.initmode.lazy;
/**
 * by https://github.com/911992
 * arashmd.blogspot.com
 */
public class LazyOne {

  private static volatile LazyOne instance=null;
  public synchronized static LazyOne getInstance(){//or it could be in double-check approach for race conditions sake
    //it checks the instance nullify for every call, sounds not so cool
        if(LazyOne.instance==null){
          LazyOne.instance=new LazyOne();
        }
    return LazyOne.instance;
  }
  private LazyOne(){
    System.out.println("Hi From Lazy One, oh I need some coffee!");
  }
}

//=============================
public class UsingLazy {
  public static void main(String[] args) {
    System.out.println("We are going to use a lazy guy...");
    LazyOne lo=LazyOne.getInstance();
    //using the guy
    //...
  }
}
As above code says, the instance is null by default, but it gets initialized by the very first getInstance() method call. the synchronized block is used for avoiding with-same-time initializing which is would appeared in multi-thread application(or the same approach for double null check).
The only lack here would be the first if block which checks the nullify of the instance every time, while this check just returns false one time, so let me introduce my customized lazy-init Singleton .

Lazy Mode By Null Object(My Kind of Lazy Mode)

Well there is no surprise, the only difference is that there is no nullify check every time. We would redirect a work as easy as ABC with multiple implementation by interfaces and abstract classes.
So I combined the Singleton with Null Object pattern. At the first the instance is initialized as a null object, not null.
A fake(null/light) instance is initialized by declaration(say eager), and just for the first request, the fake business initializes(creates) the actual business and replaces the fake business implementation with actual one. So here we are not going to check the instance null state every time, instead swap the implemntation of the businesses.

First we extract all business methods(what actually need to be done) from the singleton class to an interface or abstract class named Business. Next two classes Null Business and Actual Business implement the business interface that the null one is initialized by singleton business field declaration that just responsible to create the actual one in order to redirect all next requests to it.
There will be only one nullify checking here by null one, and singleton is ensured that business instance points permanently to the actual implementation any time.
package wasys911992.blogger.java.pattern.singleton.initmode.lazy.nullobj;
/**
 * by https://github.com/911992
 * arashmd.blogspot.com
 */

interface Business {
void doSomething();
Object getContext();
}
//=============================
class SingleGuy {
  private static SingleGuy instance=new SingleGuy();
  public static SingleGuy getInstance(){
    return SingleGuy.instance;
  }
  //by default business is null one
  private Business buss=new NullBusiness();
  //a bridge to set the actual business
  void setActualBusiness(Business buss){
    this.buss=buss;
  }
  private SingleGuy(){
    System.out.println("Singleton initilized!");
  }
  public void doWork(){
    //doing the work...
    buss.doSomething();
  }
  public Object getContext(){
    return buss.getContext();
  }
}
//==============================
class ActualBusiness implements Business {

  @Override
  public void doSomething(){
    //do some business
    System.out.println("Doing something nonesens...!");
  }

  @Override
  public Object getContext() {
    return new secret_context();
  }
}
//===============================
class NullBusiness implements Business {
  @Override
  public void doSomething(){
    initActualBusiness();
    //forward the request to the actual business
    realBusiness.doSomething();
  }
  @Override
  public String getContext() {
    initActualBusiness();
    //get and return the context from the actual business
    return realBusiness.getContext();
  }private Business realBusiness=null;
  private synchronized void initActualBusiness(){
    if(realBusiness!=null){return; }
    System.out.println("initilizing real business....");
    //Instantiate the actual business
    realBusiness=new ActualBusiness();
    //set the actual one with null one for fortune calls
    SingleGuy.getInstance().setActualBusiness(realBusiness);
  }
}

Examples

Simple Context Manager(Naming and Directory Interface, NDI)

Consider a simple central resource/context manager(NDI), clients can add, remove, or update resources. Each resource has one name and could be in anything(data-type). Also clients would listen for any(particular) resource manipulation event.

Okay, as you see in above example the ResourceManager class follows singleton rules, constructor is hidden, a pointer(instance) from itself(eager mode) which is made accessible by a static method.
The Listener interface is used for communicating between listeners and the manager, in fact manager informs the client listeners by this interface.
Class ListenerHolder, it holds listener which are belong to a certain resource, in fact each resource would have many listeners. The ResourceManager class has a map(list) of this class, because there are many resources belong to resource manager.
And finally ClientA, and ChangeListener classes, these two guys are just for testing the system and showing how does outsiders would communicate with resource manager.
And the code
package wasys911992.blogger.java.pattern.singleton.example0;
/**
 * by https://github.com/911992
 * arashmd.blogspot.com
 */
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Scanner;

public class ResourceManager {
  private static ResourceManager instance=new ResourceManager();
  public static ResourceManager getInstance(){return ResourceManager.instance;}
  private ResourceManager(){
    resources=new HashMap<String,Object>(5);
    listeners=new Hashtable<String,ListenerHolder>(5);
    //adding some default value
    resources.put("name", "Resource Manager Singleton");
    resources.put("version", 1);
    resources.put("friends", "Sahand ,Pedram ,Aidin ,Danial");
    
    System.out.println("Resource Manager Initilized");
  }

private HashMap<String, Object> resources;
private Hashtable<String, ListenerHolder> listeners;
public void addListener(String name,Listener l){
  synchronized (resources) {
    if(resources.containsKey(name)){
      if(listeners.containsKey(name)){
        listeners.get(name).addListener(l);
      }else{
        ListenerHolder lh=new ListenerHolder(l);
        listeners.put(name, lh);
      }
    }  
  }
}
public Object getObject(String name){
  return resources.get(name);
}
public void updateResource(String name,Object arg){
  synchronized (resources) {
   if(resources.containsKey(name)){
     resources.remove(name);
     resources.put(name, arg);
   } 
  }if(!listeners.containsKey(name)){return;}
  for(Listener lx : listeners.get(name).getList()){
      lx.onUpdate(name,arg);
  }
}
public void addResource(String name,Object arg){
  synchronized (resources) {
   resources.put(name, arg); 
  }
}
}
//==================================
public interface Listener{
  public void onUpdate(String name,Object arg);
}
//==================================
class ListenerHolder{
  public ListenerHolder(Listener l){this.listeners.add(l);}
  private List<Listener> listeners=new ArrayList<>(5);
  public void addListener(Listener l){listeners.add(l);}
  List<Listener> getList(){return listeners;}
}
//==================================
//and a simple client
public class ClientA{
  private ResourceManager r;
  private String sysVersion="2EB";

  private Scanner s;
    public static void main(String arg[]) {
    ClientA a=new ClientA();
    a.changeSysVersion();
  }
  public ClientA(){
    s=new Scanner(System.in);
    r=ResourceManager.getInstance();
    r.addResource("sysVersion", sysVersion);
    Listener l=new ChangeListener();
    //add l listener for "sysVersion" resource changes
    r.addListener("sysVersion", l);
    String f=(String)r.getObject("friends");
    System.out.println("Friends: "+f);
  }
  void changeSysVersion(){
    System.out.print("Enter new value for \"sysVersion\"(current value= "+sysVersion+"): ");
    String newVal=s.nextLine();
    r.updateResource("sysVersion",newVal);
  }
}
//==================================
//simple change listener
class ChangeListener implements Listener{

  @Override
  public void onUpdate(String name,Object arg) {
    System.out.println("Change Listener: updated resource("+name+") value = "+arg);    
  }
  
}
Okay, in above code, check the ClientA constructor, it gets ResourceManager instance, and add a resource name sysVersion, then adds a ChangeListener instance as resource listener for sysVersion resource, and change the value implicitly that cause resource manager triggers the related listeners.

Simple Transaction Manager

This instance is talking about a central transaction manager, this one has a singleton class TransactionMgr which takes care about transaction with a specific data source(database).
Client gets a transaction id (long long value) which points to a real transaction inside the transaction manager(assume a pointer, if you are a OOP-nism, consider use the object instead of pointer). Because transaction manager is singleton and is accessible every where in workspace, so different modules just need to use shared transaction with just one long value.
The same thing is available in J2EE, context manager, and Faces Context in jsf.

As you see in above diagram, TransactionMgr is a singleton guy, so it means the whole application would simply uses transactions in a central-ready module.
And the code, there is no need for comments. Members tell everything you need dude.
package wasys911992.blogger.java.pattern.singleton.example.tranmgr;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Properties;
/**
 * by https://github.com/911992
 * arashmd.blogspot.com
 */
public class TransactionMgr {
private static TransactionMgr instance=new TransactionMgr();
private java.sql.Driver driver=null;
private java.util.HashMap<Long, java.sql.Connection> batches=new HashMap<Long,java.sql.Connection>();
private final int maxTranInstance=16;
private int runningTransaction=0;
private long lastTranId=0;
private final String connectionString="jdbc:postgresql://127.0.0.1:17001/_ds";
private final Properties connectionPeroperties=new Properties();
private final String driverClassName="org.postgresql.Driver";
private Object waitLock=new Object();

private TransactionMgr(){
  System.out.println("Connection Manager is initializing\nusing "+this.driverClassName+" as default driver...");
  try {
    this.driver=(java.sql.Driver)Class.forName(driverClassName).newInstance();
    //setting default connection properties
    this.connectionPeroperties.put("user", "__arash_");
    this.connectionPeroperties.put("password", "one simple password!!!");
    System.out.println("Connection Manager has initialized successfully, ready for action!");
  } catch (Exception e) {
    System.err.println("Error! could not load the driver! "+e.getMessage());
    e.printStackTrace();
  }
}
public static TransactionMgr getInstance(){return TransactionMgr.instance;}
public synchronized void setDriver(String dName) throws Exception{
  this.driver=(java.sql.Driver)Class.forName(dName).newInstance();
}
public java.sql.Connection getANativeConnection() throws SQLException{
  return driver.connect(connectionString, connectionPeroperties);
}
public long beginTransaction() throws SQLException{
  synchronized (waitLock) {
    if(runningTransaction==maxTranInstance){
      try {waitLock.wait();} catch(InterruptedException e){e.printStackTrace();}
    }
    Connection c=driver.connect(connectionString, connectionPeroperties);
    c.setAutoCommit(false);
    batches.put(++lastTranId, c);
    runningTransaction++;
    return lastTranId;
  }
}
public int addToTransation(long tranId,String command) throws SQLException{
  if(!batches.containsKey(tranId)){return -2;}
  return batches.get(tranId).createStatement().executeUpdate(command);
}
public void commitTransaction(long tranId) throws SQLException{
  if(!batches.containsKey(tranId)){return;}
  batches.get(tranId).commit();
  removeTransaction(tranId);
}
public void rollbackTransaction(long tranId){
  if(!batches.containsKey(tranId)){return;}
  removeTransaction(tranId);
}
private void removeTransaction(long tranId){
  synchronized (waitLock) {
    if(!batches.containsKey(tranId)){return;}
    runningTransaction--;
    try {batches.remove(tranId).close();} catch (SQLException e) {e.printStackTrace();}
    try{waitLock.notify();}catch(Exception e){}
  }
}
}
//=====================================
public class UserInput {
  private static java.util.Scanner reader=null;
  static{
    reader=new java.util.Scanner(System.in);
  }
  public static void main(String[] args) {
    System.out.println("We are going to utilize the singleton");
    UserInput.getUserInfo();
  }
  private static void getUserInfo(){
    try{
    TransactionMgr cm=TransactionMgr.getInstance();
    //Connection c=cm.getANativeConnection();
    //c.createStatement().execute("create table \"user\"(\"name\" character varying(256))");
    long l=cm.beginTransaction();
    System.out.println("Transaction had began, please enter names you want to insert");
    System.out.println("you may input :q for rollbacking transaction, or :p for commit...");
    String name;
    while(true){
      name=reader.nextLine();
      if(name.equals(":q")){cm.rollbackTransaction(l);
      System.out.println("Transaction has rollbacked successfully....");break;}
      if(name.equals(":p")){cm.commitTransaction(l);
      System.out.println("Transaction has Commited successfully....");break;}
      cm.addToTransation(l, "insert into \"user\" values('"+name+"')");      
    }
    System.out.println("Thanks for using connection manager!");
    }catch(Exception e){e.printStackTrace();}
  }
}

Note: Prepare external dependencies(database, driver) before you test it :).
Note: I have not tested the codes, so consider get gifted by some Exceptions by dear JVM.