What is a Pattern? We’ll start with the definition of Christopher Alexander who states that “Each pattern describes a problem which occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice”.

A pattern has four essential elements

  • Pattern name
  • Problem
  • Solution
  • Consequences

Singleton Design Pattern

Intent of Singleton design pattern is to ensure that a class only has one instance, and provide a global point of access to it.

Motivation: There are times when a class can only have one instance

Applicability: Use the Singleton pattern when

  • There must be only one instance of a class, and it must be accessible to clients from a well-known access point.
  • When the sole instance should be extensible by subclassing, and clients should be able to use an extended instance without modifying their code.

Situations for Using a Singleton

  1. Java Security manager: All parts of a program must access the same security manager. Once set a security manager cannot be changed in a program
  2. Logging the activity of a server: All parts of the server should use the same instance of the logging system. The server should not be able to change the instance of the logging system was it has been set
  3. You want to limit the number of instances of a class to one. For example, In Microsoft Word you can press Ctrl-F to display a Find dialog. However, for the whole life of Microsoft Word, there can only be one Find dialog. How to solve?

Solution

The Singleton pattern can be used for above mentioned purposes. This pattern is effective for limiting the maximum number of instances of a class to exactly one. In this case, if more than one object needs to use an instance of the Singleton class, those objects share the same Singleton class instance. A class that implements the Singleton pattern is called a Singleton class.

The most common method of creating instance of a class is new keyword. For example, the following code constructs an instance of class MyClass by calling its no-argument constructor:

new MyClass()

You get one object each time a constructor is called.

How do you write a Singleton class?

Create a public static method that is solely responsible for creating the single instance of the class. The client of the class should not be able to invoke the Singleton class’s constructor. Because the absence of a constructor will make the compiler create a default constructor, a class applying the Singleton pattern has a private or protected constructor. Because the constructor is private or protected, there is no way a client can create an instance of that class by calling its constructor. The constructor is not accessible from outside of the class!

Question: If the only constructor cannot be accessed, how do we get an instance of that class?

Answer: A static method in the class that calls the constructor to create an instance of the class and return this instance to the caller of the static method. A static members of a class can be invoked without having an instance of that class. To limit the number of instances to one, the static method has to check if an instance has been created before. If it has, it simply returns a reference to the previous created instance. If it has not, it calls the constructor to create one.

Java Implementation of Singleton

// Only one object of this class can be created
class Singleton {
   private static Singleton _instance = null;
   private Singleton() {
   //fill in the blank
   }
   public static Singleton getInstance() {
      if ( _instance == null )
         _instance = new Singleton();
         return _instance;
   }
   public void otherOperations() { blank; }
}
class Program {
   public void aMethod() { X = Singleton.getInstance(); }
}

Example: SingletonFrame

	package singleton;
	import javax.swing.*;

	public class SingletonFrame extends JFrame {
	   private static SingletonFrame myInstance;
	   // the constructor
	   private SingletonFrame() {
		this.setSize(400, 100);

		this.setTitle("Singleton Frame. Timestamp:" + System.currentTimeMillis());

		this.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
	   }
	   public static SingletonFrame getInstance() {
		if (myInstance == null)
		   myInstance = new SingletonFrame();
		return myInstance;
	   }
	}

////////////////////////////
package singleton;

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

public class MyFrame extends JFrame {
  JButton jButton1 = new JButton();
  JButton jButton2 = new JButton();

  public MyFrame() {
    try {
      init();
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }
 private void init() throws Exception {
    this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    jButton1.setText("Show Singleton Frame");
    jButton1.setBounds(new Rectangle(12, 12, 220, 40));
    jButton1.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        jButton1_actionPerformed(e);
      }
    });
 jButton2.setText("Show the same Singleton Frame");
    jButton2.setBounds(new Rectangle(12, 72, 220, 40));
    jButton2.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        jButton2_actionPerformed(e);
      }
    });
    this.getContentPane().setLayout(null);
    this.getContentPane().add(jButton1, null);
    this.getContentPane().add(jButton2, null);
  }

 void jButton1_actionPerformed(ActionEvent e) {
    SingletonFrame singletonFrame = SingletonFrame.getInstance();
    singletonFrame.setVisible(true);
  }

 void jButton2_actionPerformed(ActionEvent e) {
    SingletonFrame singletonFrame = SingletonFrame.getInstance();
    singletonFrame.setVisible(true);
  }

  public static void main(String[] args) {
    MyFrame frame = new MyFrame();
    frame.setSize(300, 250);
    frame.setVisible(true);
  }
}

Singleton and Inheritance

Java can not create a static instance of subclass in file that contains the subclass implementation. Protection level problem with constructor. Classes in the same package can access protected constructors. If subclass makes constructor private than even parent can not access child’s constructor.

Solution

  • Use Class.forName(), static block, and registry
  • Keeping Singleton classes in different package from clients allows constructors to be protected.
  • Solution when constructors can be protected is simpler

Class.forName

class Example {
   public String toString() {
        return "This is a simple class";
   }
}
class Test {
   public static void main( String args[] ) throws Exception {
       Class which = Class.forName( "Example" );
       Object whichOne = which.newInstance();
       System.out.println( whichOne.toString() );
   }
}

Singleton Class

abstract class Singleton {
    private static Singleton _instance = null;
    public static void setInstance( Singleton registerer) {
       if ( _instance != null )
          _ instance =registerer ;
    }
    public static void setInstance( String className ) {
       Class aSingleton = Class.forName( className );
       if ( isSubclassOfSingleton( aSingleton ) ) {
         Class[] noArgs = new Class[0];
         Method register = aSingleton.getMethod( "register", noArgs );
         register.invoke( null, noArgs);
       }
     }
     public static Singleton getInstance() {
        if ( _instance == null )
           _instance = getDefaultSingleton();
        return _instance;
      }
  }

Inheritance with singleton

class Child extends Singleton {
   public static void register() {
       Singleton.setInstance( new Child() );
   }
   private Child() { what ever you need to do; }
}

C++ Implementation of Singleton

// Only one object of this class can be created
class Singleton {
	   private:
                     static Singleton* _instance;
                     void otherOperations();
         protected:
                     Singleton();
         public: static Singleton* getInstance();
       }  Implementation Singleton* Singleton::_instance = 0;
      Singleton* Singleton::getInstance() {
         if ( _instance == 0 ) _instance = new Singleton;
         return _instance;
      }

Defines an getInstance operation that lets clients access its unique instance. May be responsible for creating its   own unique instance.

Consequences

  • Controlled access to sole instance
  • Reduced name space
  • Permits subclassing
  • Permits a variable number of instances
  • More flexible than class operations
Tagged with: Design PatternJAVAObject Oriented
 

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

 

Looking for something?

Use the form below to search the site:


Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

Related News Feeds

Set your Twitter account name in your settings to use the TwitterBar Section.