Singleton
Agenda Singleton – Intent Singleton classic - Java 5 Case study – To implement singleton. Singleton – IOC
Singleton Intent Singleton pattern  ensures a class has  only one instance ,  and provides a global point of access to it. Advantages Controlled Access to sole instance Reduced name space (Global variable) Provides a variable number of instances More flexible
Singleton Classic CacheManager.getInstance() private constructor public class CacheManager { private static final CacheManager CACHE_MGR = new CacheManager (); private CacheManager {} private Map<String,Object> cache; public static CacheManager  getInstance() { return CACHE_MGR; } public Object get(String key) { //code for getting the object from cache; }}
Singleton Classic – Java 5 Boiler plate code for getInstance(), private constructor avoided. import static CacheManager.CACHE_MGR; public class CacheClient{ public static void main(String a[]){ CACHE_MGR.get(“testCache”); }} public  enum  CacheManager { CACHE_MGR; private Map<String,Object> cache; public Object get(String key) { //code for getting the object from cache; } public void put(String key,Object val) { //code for put the object in cache; } }
Case - Study
Notice Board detailed Domain
OnSubmit for send Message Static binding Singleton as Evil
Singleton public class MessageBroadCaster { private static final MessageBroadCaster INSTANCE = new MessageBroadCaster();  private MessageBroadCaster() {} public static MessageBroadCaster  getInstance () { return INSTANCE; } public void broadCast(final String[] messages) { final NoticeBoard board = NoticeBoard.getInstance(); int i = 0; final Message[] todayMessages = new Message[messages.length]; for(final String message : messages) { todayMessages[i++] = new Message(message); } board.show(todayMessages); } } public class NoticeBoard { private static final NoticeBoard noticeBoardInstance = new NoticeBoard(); private NoticeBoard   () {} public static NoticeBoard  getInstance () { return noticeBoardInstance;  } public void show(final Message[] messages){ for(Message msg : messages) msg.display();  } } Global Variables are many … Class operation
Change We need more notice boards to broadcast the message Electronic Notice board LCD Notice Board ..much more How we can add these change ? Great  OO software must have Flexible
Patterns Patterns are used to solve the common set of problems Don’t start to think on patterns. Choose patterns which is very relative and solve your problem ( If we found)
Abstraction
public class MessageBroadCaster{ private NoticeBoard noticeBoard; public MessageBroadCaster(NoticeBoard noticeBoard) { this.noticeBoard = noticeBoard; }  public void broadCast(final String[] messages) { int i = 0; final Message[] todayMessages = new Message[messages.length]; for(final String message : messages) { todayMessages[i++] = new Message(message); } noticeBoard.show(todayMessages); } } Abstraction class Simple implements NoticeBoard{ public void show(Message[] messages) { System.out.println(&quot;Simple Display ...&quot;); for(Message message: messages) { System.out.println(message.getContent()); } } } Instance operation, with good abstraction
Modules Sequence Simple Messenger Simple Message  Broadcaster Simple  Notice Board sends broadcast Simple LCD Messenger LCD Message  Broadcaster LCD  Notice Board sends broadcast LCD Electronic Messenger Electronic Message  Broadcaster Electronic  Notice Board sends broadcast Electronic This is not a
How to create Messenger for other modules like LCD,Electronic ..etc public class Messenger  { private MessageBroadCaster messageBroadCaster; public Messenger(MessageBroadCaster messageBroadCaster) { this.messageBroadCaster = messageBroadCaster; } public void send(String[] messages) { messageBroadCaster.broadCast(messages); } public static void main(String[] args) { NoticeBoard  simpleNoticeBoard  = new  Simple (); MessageBroadCaster simpleMessageBroadCaster = new MessageBroadCaster(simpleNoticeBoard) ; Messenger simpleMessenger = new Messenger(simpleMessageBroadCaster); simpleMessenger.send (new String[] { &quot;Welcome to Singleton&quot; , &quot;Town hall meet&quot; }); } } Simple Module Simple Notice Board flow or Module has been tested.
Solve the problem of creation Good programming practice (idioms) will help us to solve Depends on abstraction not to implementation. Singleton    if needed.
Program Idiom public class NoticeBoardFactory { public NoticeBoard createNoticeBoard(String type)  { if(&quot;Simple&quot;.equals(type)) { return new Simple(); } else if(&quot;LCD&quot;.equals(type)){ return new LCD(); } else if(&quot;Electronic&quot;.equals(type)) { return new Electronic(); } else { return null; }}} public static void main(String[] args)  { NoticeBoardFactory boardFactory = new NoticeBoardFactory(); NoticeBoard simpleNoticeBoard =  boardFactory.createNoticeBoard(&quot;Simple&quot;);   MessageBroadCaster simpleMessageBroadCaster = new MessageBroadCaster(simpleNoticeBoard); Messenger simpleMessnger = new Messenger(simpleMessageBroadCaster); simpleMessnger.send(new String[] { &quot;Welcome to Singleton&quot; , &quot;Town hall meet&quot; }); } Note: We can avoid this if instead use Map, to look for specific type Creation of NoticeBoard becomes Abstract, using a program idiom
Module - IOC class MessengerModule{ private NoticeBoard noticeBoard; private MessageBroadCaster messageBroadCaster; private Messenger messenger; public MessengerModule(String type) { noticeBoard =  new NoticeBoardFactory().createNoticeBoard(type); messageBroadCaster =  new MessageBroadCaster(noticeBoard); messenger =  new Messenger(messageBroadCaster); } public void send(String[] messages) { messenger.send(messages); } } MessengerModule simpleModule = new MessengerModule(&quot;Simple&quot;); simpleModule.send(new String[] { &quot;Welcome to Singleton&quot; , &quot;Town hall meet&quot; }); MessengerModule lcdModule = new MessengerModule(&quot;LCD&quot;); lcdModule.send(new String[] { &quot;Welcome to Singleton&quot; , &quot;Town hall meet&quot; }); MessengerModule electronicModule = new MessengerModule(&quot;Electronic&quot;);   electronicModule.send(new String[] { &quot;Welcome to Singleton&quot; , &quot;Town hall meet&quot; });
Is flexible ? BroadCaster behavior is different based on the messenger SimpleBroadCaster creates Simple Message LCDBroadCaster creates LCD Message ElectronicBroadCaster creates Electronic Message Can we apply it in our design ?
Flexible
Module – More Abstraction class MessengerModule{ private NoticeBoard noticeBoard; private MessageBroadCaster messageBroadCaster; private Messenger messenger; public MessengerModule(String type) { noticeBoard =  new NoticeBoardFactory().createNoticeBoard(type); messageBroadCaster =  new MessageBroadCasterFactory().createMessageBroadCaster(type,noticeBoard); messenger =  new MessengerFactory().createMessenger(type, messageBroadCaster); } public void send(String[] messages) { messenger.send(messages); }}
Module - Control Messenger module object gives access to the messenger for the client We need only 3 set messenger objects Simple LCD Electronic How to solve this problem ?
class MessengerModule{ private NoticeBoard noticeBoard; private MessageBroadCaster messageBroadCaster; private Messenger messenger; private static final Map<String, MessengerModule> MSG_MODULES = new HashMap<String, MessengerModule>(); public static MessengerModule getInstance(String type)  { MessengerModule messengerModule =  MSG_MODULES.get(type); if(messengerModule == null)  { messengerModule = new MessengerModule(type); MSG_MODULES.put(type,messengerModule); } return messengerModule; } private MessengerModule(String type) { noticeBoard = new NoticeBoardFactory().createNoticeBoard(type); messageBroadCaster = new MessageBroadCasterFactory().createMessageBroadCaster(type,noticeBoard); messenger = new MessengerFactory().createMessenger(type, messageBroadCaster);} public void send(String[] messages) { messenger.send(messages); } } Module – Singleton Classic
Module – Singleton – Java5 enum MessengerModule { Simple,LCD, Electronic; private NoticeBoard noticeBoard; private MessageBroadCaster messageBroadCaster; private Messenger messenger; public static MessengerModule getInstance(String type) { return valueOf(type); } private MessengerModule() { noticeBoard = new NoticeBoardFactory().createNoticeBoard(this.name()); messageBroadCaster = new MessageBroadCasterFactory().createMessageBroadCaster(this.name(),noticeBoard); messenger = new MessengerFactory().createMessenger(this.name(), messageBroadCaster); } public void send(String[] messages){ messenger.send(messages); }}
Test public class MessengerClient { public static void main(String[] args){ String[] messages = new String[] { &quot;Welcome to Singleton&quot; , &quot;Town hall meet&quot; }; MessengerModule.LCD.send(messages); MessengerModule.getInstance(&quot;Simple&quot;).send(messages); MessengerModule.getInstance(&quot;Electronic&quot;).send(messages); } } Output LCD Display ... Welcome to Singleton Town hall meet Simple Display ... Welcome to Singleton Town hall meet Electronic Display ... Welcome to Singleton Town hall meet
Summary Singleton is a good pattern easy to apply, but ask more questions before going to implement Don't make Singleton for ONLY HAVE SINGLE OBJECT, unless you really need .. Singleton has to provide access to set of Objects Most applied when you have Factory (Creator) object OR Facade (Controller)  Object. Strive for loosely coupled (De-coupled) collaboration
Refferences Guice / Spring DI framework Books Applying Uml Patterns  Head First Design Patterns GOF patterns(Elements of re-usable OO Software) Effective Java
Thanks ...

Singleton

  • 1.
  • 2.
    Agenda Singleton –Intent Singleton classic - Java 5 Case study – To implement singleton. Singleton – IOC
  • 3.
    Singleton Intent Singletonpattern ensures a class has only one instance , and provides a global point of access to it. Advantages Controlled Access to sole instance Reduced name space (Global variable) Provides a variable number of instances More flexible
  • 4.
    Singleton Classic CacheManager.getInstance()private constructor public class CacheManager { private static final CacheManager CACHE_MGR = new CacheManager (); private CacheManager {} private Map<String,Object> cache; public static CacheManager getInstance() { return CACHE_MGR; } public Object get(String key) { //code for getting the object from cache; }}
  • 5.
    Singleton Classic –Java 5 Boiler plate code for getInstance(), private constructor avoided. import static CacheManager.CACHE_MGR; public class CacheClient{ public static void main(String a[]){ CACHE_MGR.get(“testCache”); }} public enum CacheManager { CACHE_MGR; private Map<String,Object> cache; public Object get(String key) { //code for getting the object from cache; } public void put(String key,Object val) { //code for put the object in cache; } }
  • 6.
  • 7.
  • 8.
    OnSubmit for sendMessage Static binding Singleton as Evil
  • 9.
    Singleton public classMessageBroadCaster { private static final MessageBroadCaster INSTANCE = new MessageBroadCaster(); private MessageBroadCaster() {} public static MessageBroadCaster getInstance () { return INSTANCE; } public void broadCast(final String[] messages) { final NoticeBoard board = NoticeBoard.getInstance(); int i = 0; final Message[] todayMessages = new Message[messages.length]; for(final String message : messages) { todayMessages[i++] = new Message(message); } board.show(todayMessages); } } public class NoticeBoard { private static final NoticeBoard noticeBoardInstance = new NoticeBoard(); private NoticeBoard () {} public static NoticeBoard getInstance () { return noticeBoardInstance; } public void show(final Message[] messages){ for(Message msg : messages) msg.display(); } } Global Variables are many … Class operation
  • 10.
    Change We needmore notice boards to broadcast the message Electronic Notice board LCD Notice Board ..much more How we can add these change ? Great OO software must have Flexible
  • 11.
    Patterns Patterns areused to solve the common set of problems Don’t start to think on patterns. Choose patterns which is very relative and solve your problem ( If we found)
  • 12.
  • 13.
    public class MessageBroadCaster{private NoticeBoard noticeBoard; public MessageBroadCaster(NoticeBoard noticeBoard) { this.noticeBoard = noticeBoard; } public void broadCast(final String[] messages) { int i = 0; final Message[] todayMessages = new Message[messages.length]; for(final String message : messages) { todayMessages[i++] = new Message(message); } noticeBoard.show(todayMessages); } } Abstraction class Simple implements NoticeBoard{ public void show(Message[] messages) { System.out.println(&quot;Simple Display ...&quot;); for(Message message: messages) { System.out.println(message.getContent()); } } } Instance operation, with good abstraction
  • 14.
    Modules Sequence SimpleMessenger Simple Message Broadcaster Simple Notice Board sends broadcast Simple LCD Messenger LCD Message Broadcaster LCD Notice Board sends broadcast LCD Electronic Messenger Electronic Message Broadcaster Electronic Notice Board sends broadcast Electronic This is not a
  • 15.
    How to createMessenger for other modules like LCD,Electronic ..etc public class Messenger { private MessageBroadCaster messageBroadCaster; public Messenger(MessageBroadCaster messageBroadCaster) { this.messageBroadCaster = messageBroadCaster; } public void send(String[] messages) { messageBroadCaster.broadCast(messages); } public static void main(String[] args) { NoticeBoard simpleNoticeBoard = new Simple (); MessageBroadCaster simpleMessageBroadCaster = new MessageBroadCaster(simpleNoticeBoard) ; Messenger simpleMessenger = new Messenger(simpleMessageBroadCaster); simpleMessenger.send (new String[] { &quot;Welcome to Singleton&quot; , &quot;Town hall meet&quot; }); } } Simple Module Simple Notice Board flow or Module has been tested.
  • 16.
    Solve the problemof creation Good programming practice (idioms) will help us to solve Depends on abstraction not to implementation. Singleton  if needed.
  • 17.
    Program Idiom publicclass NoticeBoardFactory { public NoticeBoard createNoticeBoard(String type) { if(&quot;Simple&quot;.equals(type)) { return new Simple(); } else if(&quot;LCD&quot;.equals(type)){ return new LCD(); } else if(&quot;Electronic&quot;.equals(type)) { return new Electronic(); } else { return null; }}} public static void main(String[] args) { NoticeBoardFactory boardFactory = new NoticeBoardFactory(); NoticeBoard simpleNoticeBoard = boardFactory.createNoticeBoard(&quot;Simple&quot;); MessageBroadCaster simpleMessageBroadCaster = new MessageBroadCaster(simpleNoticeBoard); Messenger simpleMessnger = new Messenger(simpleMessageBroadCaster); simpleMessnger.send(new String[] { &quot;Welcome to Singleton&quot; , &quot;Town hall meet&quot; }); } Note: We can avoid this if instead use Map, to look for specific type Creation of NoticeBoard becomes Abstract, using a program idiom
  • 18.
    Module - IOCclass MessengerModule{ private NoticeBoard noticeBoard; private MessageBroadCaster messageBroadCaster; private Messenger messenger; public MessengerModule(String type) { noticeBoard = new NoticeBoardFactory().createNoticeBoard(type); messageBroadCaster = new MessageBroadCaster(noticeBoard); messenger = new Messenger(messageBroadCaster); } public void send(String[] messages) { messenger.send(messages); } } MessengerModule simpleModule = new MessengerModule(&quot;Simple&quot;); simpleModule.send(new String[] { &quot;Welcome to Singleton&quot; , &quot;Town hall meet&quot; }); MessengerModule lcdModule = new MessengerModule(&quot;LCD&quot;); lcdModule.send(new String[] { &quot;Welcome to Singleton&quot; , &quot;Town hall meet&quot; }); MessengerModule electronicModule = new MessengerModule(&quot;Electronic&quot;); electronicModule.send(new String[] { &quot;Welcome to Singleton&quot; , &quot;Town hall meet&quot; });
  • 19.
    Is flexible ?BroadCaster behavior is different based on the messenger SimpleBroadCaster creates Simple Message LCDBroadCaster creates LCD Message ElectronicBroadCaster creates Electronic Message Can we apply it in our design ?
  • 20.
  • 21.
    Module – MoreAbstraction class MessengerModule{ private NoticeBoard noticeBoard; private MessageBroadCaster messageBroadCaster; private Messenger messenger; public MessengerModule(String type) { noticeBoard = new NoticeBoardFactory().createNoticeBoard(type); messageBroadCaster = new MessageBroadCasterFactory().createMessageBroadCaster(type,noticeBoard); messenger = new MessengerFactory().createMessenger(type, messageBroadCaster); } public void send(String[] messages) { messenger.send(messages); }}
  • 22.
    Module - ControlMessenger module object gives access to the messenger for the client We need only 3 set messenger objects Simple LCD Electronic How to solve this problem ?
  • 23.
    class MessengerModule{ privateNoticeBoard noticeBoard; private MessageBroadCaster messageBroadCaster; private Messenger messenger; private static final Map<String, MessengerModule> MSG_MODULES = new HashMap<String, MessengerModule>(); public static MessengerModule getInstance(String type) { MessengerModule messengerModule = MSG_MODULES.get(type); if(messengerModule == null) { messengerModule = new MessengerModule(type); MSG_MODULES.put(type,messengerModule); } return messengerModule; } private MessengerModule(String type) { noticeBoard = new NoticeBoardFactory().createNoticeBoard(type); messageBroadCaster = new MessageBroadCasterFactory().createMessageBroadCaster(type,noticeBoard); messenger = new MessengerFactory().createMessenger(type, messageBroadCaster);} public void send(String[] messages) { messenger.send(messages); } } Module – Singleton Classic
  • 24.
    Module – Singleton– Java5 enum MessengerModule { Simple,LCD, Electronic; private NoticeBoard noticeBoard; private MessageBroadCaster messageBroadCaster; private Messenger messenger; public static MessengerModule getInstance(String type) { return valueOf(type); } private MessengerModule() { noticeBoard = new NoticeBoardFactory().createNoticeBoard(this.name()); messageBroadCaster = new MessageBroadCasterFactory().createMessageBroadCaster(this.name(),noticeBoard); messenger = new MessengerFactory().createMessenger(this.name(), messageBroadCaster); } public void send(String[] messages){ messenger.send(messages); }}
  • 25.
    Test public classMessengerClient { public static void main(String[] args){ String[] messages = new String[] { &quot;Welcome to Singleton&quot; , &quot;Town hall meet&quot; }; MessengerModule.LCD.send(messages); MessengerModule.getInstance(&quot;Simple&quot;).send(messages); MessengerModule.getInstance(&quot;Electronic&quot;).send(messages); } } Output LCD Display ... Welcome to Singleton Town hall meet Simple Display ... Welcome to Singleton Town hall meet Electronic Display ... Welcome to Singleton Town hall meet
  • 26.
    Summary Singleton isa good pattern easy to apply, but ask more questions before going to implement Don't make Singleton for ONLY HAVE SINGLE OBJECT, unless you really need .. Singleton has to provide access to set of Objects Most applied when you have Factory (Creator) object OR Facade (Controller) Object. Strive for loosely coupled (De-coupled) collaboration
  • 27.
    Refferences Guice /Spring DI framework Books Applying Uml Patterns Head First Design Patterns GOF patterns(Elements of re-usable OO Software) Effective Java
  • 28.