Apex Implementing Singleton Design Pattern

Singleton is pretty popular and one of the most simple design patterns. On many occasions, we want an Apex class to have a single instance only. Fortunately, it's possible and pretty easy with Apex. There can be different strategies to implement singleton in Apex (inspired by my Java days learning). Before that, the following are the prerequisites to make a class Singleton.

  • There can be a static public method in class that returns the “Single” instance. Popular names for it are “self()” and “getInstance()” OR one can declare a public static property with only a public get accessor and private set accessor. I will show this in a while.

  • A constructor should have the access modifier “private”. This is a must because it will restrict other apex classes from creating the instance directly.

As I said, there can be many ways to implement Singleton.

Simple Apex Singleton Strategy

This strategy is a simple Apex Singleton strategy. I said it's “simple” because in this implementation we are assuming there will be no DML inside the constructor or static block. Here is the implementation:

public class ApexSimpleSingleton {
  /*
    Note: this is the static handle to the single class reference.
    Its set accessor is made private to dis-allow any modifications to the reference 
  */
  public static ApexSimpleSingleton self {get; private set;}
  
  static {
    // Static block used for transparent Singleton setup. the "self" static variable
    // will be ready as soon as class will be loaded in memory.
    self = new ApexSimpleSingleton();  
  }
  
  // NOTE: the constructor is marked "PRIVATE"
  // so that no Apex code outside this class can create 
  // the instance
  private ApexSimpleSingleton() {
    // Do all the non DML initalization here
  }
  
  // ..
  // ....
  // Rest of the code can be instance level methods that
  // provide access through the single handle
    
  public void sayHello() {
    System.debug('Hello World');
  }

  // TEST METHOD
  public static testmethod void testSingleton() {
    //Will print "Hello World" on console.
    ApexSimpleSingleton.self.sayHello();
  }
}

Advanced Apex Singleton Strategy

The limitation of the Simple Apex singleton strategy is that it's not meant to be used in cases where singleton initialization requires some DML code to execute. For that scenario, we need to set up the class a little differently. Here is the sample:

  public class ApexAdvancedSingleton {
  
  //Note: this is the static handle to the single class reference.
  //Its completely hidden to outside world. PRIVATE access modifier used   
  private static ApexAdvancedSingleton self;
  
  // NOTE: the constructor is marked PRIVATE
  // so that no Apex code outside this class can create the instance
  private ApexAdvancedSingleton() {
    // Do all the non DML initalization here
  }
  
  /*
    This static method will be the only way to get the Single 
    instance of this class.
  */
  public static ApexAdvancedSingleton getInstance() {
    // "self" is NOT NULL, that means we already did 
    // required initalization, so just return.
    if (self != null) return self;
      
      // Create the single instance now. 
      self = new ApexAdvancedSingleton();
      
      // All the DML Stuff to do the required one time setup. For example
      // you can use this code to create Org Wide custom settings 
      // if they don't exist.
      // ........................
      // ................................
      // ........................
      
      return self;
  }  
  
  // ..
  // ....
  // Rest of the code can be instance level methods that
  // provide access through the single handle
  
  public void sayHello() {
    System.debug('Hello World');
  }

  // TEST METHOD
  public static testmethod void testSingleton() {
    //Will print "Hello World" on console.
    ApexAdvancedSingleton.getInstance().sayHello();
  }
}

Lots of inline code comments to make this more readable and self-understandable. Apex test methods are added at the end of each Singleton sample; this also shows how to use Singleton in client Apex Code.

Still, if you feel some gaps or have some queries, please feel free to ask in the comments.

Let’s Talk

Drop a note below to move forward with the conversation 👇🏻

Abhinav Gupta

First Indian Salesforce MVP, rewarded Eight times in a row, has been blogging about Salesforce, Cloud, AI, & Web3 since 2011. Founded 1st Salesforce Dreamin event in India, called “Jaipur Dev Fest”. A seasoned speaker at Dreamforce, Dreamin events, & local meets. Author of many popular GitHub repos featured in official Salesforce blogs, newsletters, and books.

https://abhinav.fyi
Previous
Previous

Secure YUI Combo Usage Guide

Next
Next

Custom Settings – Null Pointer Exception Quick Fix!