The Singleton design pattern restricts the use of the class to a single instantiation of one object. This is required when one has to coordinate and control the object across the appliction.
This design pattern:- limits and enforces a class to only one instance
- provides a mechanism for accessibility
- provides a mechanism of instantiation
Normal instantiation is typically blocked by declaring all constructors to be private, thus enforcing the programmer to use the mechanism (with constraints) provided by the class.
This example is for a Java Singleton which provides global access to variables X and Y.
File: projx/src/com/megacorp/projx/GlobalModel.javapackage com.megacorp.projx; public class GlobalModel { private static GlobalModel INSTANCE = null; private static int X; private static int Y; private GlobalModel() { X = 0; Y = 0; } public static GlobalModel getInstance() { if (INSTANCE == null) { INSTANCE = new GlobalModel(); } return INSTANCE; } public synchronized void setX(int var) { X = var; } public synchronized int getX() { return X; } public synchronized void setY(int var) { Y = var; } public synchronized int getY() { return Y; } }
The use of the constructor GlobalModel() is forbidden by the fact that it is "private". One must use the getInstance() method as the only valid way to access and instantiate the class.
Note that the set and get methods are "synchronized". This is a good practice for concurrency where multiple threads may be accessing X or Y at the same time.
The main application
File: projx/src/com/megacorp/projx/Main.javapackage com.megacorp.projx; public class Main { public static void main(String[] args) { GlobalModel globalModel = GlobalModel.getInstance(); globalModel.setX(4); System.out.println("X=" + globalModel.getX()); System.out.println("Y=" + globalModel.getY()); } }
This example works across threads and classes to easily access shared data.
File: projx/build.xml<?xml version="1.0" encoding="utf-8"?> <project name="Singleton Demo" default="jar" basedir="."> <description>Builds and runs the project X Singleton Demo.</description> <property name="build.dir" location="./classes" /> <property name="src.dir" location="./src" /> <property name="jar.file" value="app.jar" /> <path id="classpath"> <pathelement location="." /> </path> <target name="compile"> <mkdir dir="${build.dir}"/> <javac destdir="${build.dir}" debug="true" includeAntRuntime="false"> <src path="${src.dir}" /> <classpath refid="classpath" /> </javac> </target> <target name="jar" depends="compile"> <jar jarfile="app.jar"> <manifest> <attribute name="Main-Class" value="com.megacorp.projx.Main" /> <attribute name="Class-Path" value="classpath" /> </manifest> <fileset dir="${build.dir}" includes="**/*.class" /> </jar> </target> <target name="run" depends="jar"> <java classname="com.megacorp.projx.Main" failonerror="true" fork="true"> <classpath> <path refid="classpath" /> <path location="${jar.file}"/> </classpath> </java> </target> <target name="clean"> <delete dir="${build.dir}"/> <delete file="${jar.file}"/> </target> </project>
Building and run:
- Build: ant
- Run: ant run
projx$ ant Buildfile: /home/ipp/JUNK/projx/build.xml compile: [mkdir] Created dir: /home/ipp/JUNK/projx/classes [javac] Compiling 2 source files to /home/ipp/JUNK/projx/classes jar: [jar] Building jar: /home/ipp/JUNK/projx/app.jar BUILD SUCCESSFUL Total time: 0 seconds projx$ ant run Buildfile: /home/ipp/JUNK/projx/build.xml compile: jar: run: [java] X=4 [java] Y=0 BUILD SUCCESSFUL Total time: 0 seconds
The Singleton design pattern can also be enforced through inheritance. This does not allow one to inherit multiple derived classes from a single singleton base class as the single instance rule applies to both the base class and to the derived class. This pattern could be used, for example, with a base logger class where a single instance enforcement is required, but inheritance will allow the capability of the logger class to be extended.