Singleton Pattern Demo

 

package SingletonPatternDemo; // Class to handle the singleton instance of ReportHeader public class ReportHeader { // Static variable to hold the single instance, marked as volatile to ensure visibility // of changes across threads. private static volatile ReportHeader instance; // Private variable to hold the header text private String header; // Private constructor to prevent instantiation from outside the class private ReportHeader() { // Initializes the header string with specific details this.header = "ABC Programming Company\nSan Antonio Office\n210-837-1234\n\n"; } // Public method to get the singleton instance public static ReportHeader getInstance() { // First check to see if an instance already exists without locking if (instance == null) { // Synchronize on the class object to ensure only one thread can enter // this block at a time. synchronized (ReportHeader.class) { // Double check to make sure the instance was not created in another thread // while the current thread was waiting on the class' lock. if (instance == null) { // If the instance is still null, create a new one instance = new ReportHeader(); } } } // Return the instance return instance; } // Getter method for the header string public String getHeader() { return this.header; } // Method to print the header to the console public void printHeader() { System.out.println(this.header); } }

Key Points of the Singleton Pattern:

  1. Single Instance: Ensures that a class has only one instance and provides a global point of access to it.

  2. Thread Safety: The use of volatile and double-checked locking helps to keep the singleton instance updates visible and synchronized across threads while minimizing locking overhead.

  3. Lazy Initialization: The instance of ReportHeader is not created until the getInstance() method is called. This is beneficial if the instance creation is resource-intensive and/or the instance is optional for some time after the program starts.

package SingletonPatternDemo; public class SingletonDemo { public static void main(String[] args) { ReportHeader reportHeader = ReportHeader.getInstance(); reportHeader.printHeader(); // Using the new printHeader method // Write report } }

Let's consider a Report Header Singleton class that provides a consistent header for all reports generated by the system. The Singleton ensures that we only create one instance of the header for efficiency and consistency.

In the above example, ReportHeader is our Singleton class. It contains a private header string that holds the report header. The getInstance method provides access to the Singleton instance.

The ReportWriter class uses the Singleton to retrieve the report header. When the ReportWriter is run, it will print the report header to the console.

This example ensures there is always a single, consistent header used across all reports in the application.

COSC-1437 / ITSE-2457 Computer Science Dept. - Author: Dr. Kevin Roark