A static class with a load of static variables is a bit hacked.
public static class Ugly { private static int count; public synchronized static void increment(){ count++; } public synchronized static void decrement(){ count--; if( count<0 ) { count=0; } } public synchronized static boolean isClear(){ return count==0; } }
The syntax with the actual instance is better.
public static class LessUgly { private static LessUgly instance; private int count; private LessUgly(){ } public static synchronized getInstance(){ if( instance==null){ instance = new LessUgly(); } return instance; } public synchronized void increment(){ count++; } public synchronized void decrement(){ count--; if( count<0 ) { count=0; } } public synchronized boolean isClear(){ return count==0; } }
The state is ONLY in the instance.
This way singleton can be modified later to do pooling, streaming local instances, etc. And not one of the code already written needs to be changed in order to benefit.
public static class LessUgly { private static Hashtable<String,LessUgly> session; private static FIFO<LessUgly> freePool = new FIFO<LessUgly>(); private static final POOL_SIZE=5; private int count; private LessUgly(){ } public static synchronized getInstance(){ if( session==null){ session = new Hashtable<String,LessUgly>(POOL_SIZE); for( int i=0; i < POOL_SIZE; i++){ LessUgly instance = new LessUgly(); freePool.add( instance) } } LessUgly instance = session.get( Session.getSessionID()); if( instance == null){ instance = freePool.read(); } if( instance==null){
You can do something similar with a static class, but there will be overhead in indirect dispatch.
You can get an instance and pass it to the function as an argument. This allows you to pass the code to the "right" singleton. We know that you only need one of them ... until you do.
The big advantage is that state-based syntaxes can be thread-safe, while a static class cannot, unless you change it to a secret singleton.
Tim Williscroft Sep 07 '08 at 23:30 2008-09-07 23:30
source share