Apex Design Patterns Series – The Singleton Pattern

on

|

views

and

comments

Table of Contents

Introduction

Apex allows us to develop any custom solution. This post is an aggregate of common design patterns and associated best practices for Apex development. Knowing these patterns will not only help you achieve excellence in daily development but also will prepare you to rock any Developer interview.

Types of Design pattern

Singleton — minimizing object instantiation for improved performance and to mitigate the impact of governor limits
Strategy — defining a family of algorithms, encapsulating each one and making them interchangeable and selectable at runtime
Decorator — extending the functionality of a sObject in Apex
Bulk State Transition — efficiently tracking the change of a field value in a trigger and executing functionality based on this change
Composite — treating a group of objects in a similar manner to a single instance of that object

The Singleton Pattern

  • Ensure a class has only one instance, and provide a global point of access to it.
  • Encapsulated “just-in-time initialization” or “initialization on first use“.

Intent

The intent of the Singleton pattern is to provide only a single instance of the class and that instance can be used anywhere throughout the transaction.

In other words,

The application needs one, and only one, an instance of an object. Additionally, lazy initialization and global access are necessary.

Structure

The Singleton Pattern Structure

Example

The Singleton pattern ensures that a class has only one instance and provides a global point of access to that instance. 

The office of the President of the India is a Singleton. The Indian Constitution specifies the means by which a president is elected, limits the term of office, and defines the order of succession. As a result, there can be at most one active president at any given time. Regardless of the personal identity of the active president, the title, “The President of the India” is a global point of access that identifies the person in the office.

Credit – https://sourcemaking.com/design_patterns/singleton

What iT takes to develop Singleton pattern

  • Public Property that needs to be accessed by developers/users
  • Private Instance of the Apex Class
  • Private constructor to run the code
  • Public static method that a developer can refer to in the code

Problem Statement

Let’s say you are integrating the Stripe Payment gateway with Salesforce and need to send the data to Stripe on certain actions. For Example, Account Creation.

You have developed the following apex call as initial version

InItial Version - v1

				
					public with sharing class SingletonClass {
    
    public static void createPaymentInStripe(Payment__c payment) {
        StripeConfig__c stripeConfig = new QueryFactory.QueryBuilder<StripeConfig__c>()
            .selectFrom(StripeConfig__c.class)
            .query()
            .first();
        // Make Stripe API Callout to create a Payment in Stripe using Http Class

    }

    public static void createCustomerInStripe(Account customer) {
        StripeConfig__c stripeConfig = new QueryFactory.QueryBuilder<StripeConfig__c>()
            .selectFrom(StripeConfig__c.class)
            .query()
            .first();
        // Make Stripe API Callout to create a Customer in Stripe using Http Class
    }
}

				
			

If you notice that, in the above code we are making the SOQL query for both the methods and there could be more methods. Now consider, that if there is bulk data then you will get into SOQL Governor Limit.

Let’s modify the code and have a separate method do make the SOQL Query

Modified - v2

				
					public with sharing class SingletonClass {
    
    public static StripeConfig__c queryConfig(){
        StripeConfig__c stripeConfig = new QueryFactory.QueryBuilder<StripeConfig__c>()
            .selectFrom(StripeConfig__c.class)
            .query()
            .first();
        return stripeConfig;
    }
    public static void createPaymentInStripe(Payment__c payment) {
        StripeConfig__c stripeConfig = queryConfig();
        // Make Stripe API Callout to create a Payment in Stripe using Http Class

    }

    public static void createCustomerInStripe(Account customer) {
        StripeConfig__c stripeConfig = queryConfig();
        // Make Stripe API Callout to create a Customer in Stripe using Http Class
    }
}

				
			

We have made the changes and kept the query in a separate method. However still if there are many records you will get into Governor Limit.

Let’s develop the same using the Singleton pattern.

Using Single Pattern

				
					public with sharing class SingletonClass {

    /* Create the private instance of SingletonClass */
    private static SingletonClass instance;
    /* Create the public varibale to store the StripeConfig__c */
    public static StripeConfig__c stripeConfig;

    /* Create a private constructor to prevent the creation of an instance of the class */
    private SingletonClass() {
        stripeConfig = new QueryFactory.QueryBuilder<StripeConfig__c>()
        .selectFrom(StripeConfig__c.class)
        .query()
        .first();
    }

    /* create the publically available resource to get the instance of the class */
    public static SingletonClass getInstance(){
        if(instance == null){
            instance = new SingletonClass();
        }
        return instance;
    }
    public static void createPaymentInStripe(Payment__c payment) {
        SingletonClass.getInstance();
        /* Stripe Configuration variable will become available here */
        // Make Stripe API Callout to create a Payment in Stripe using Http Class

    }

    public static void createCustomerInStripe(Account customer) {
        SingletonClass.getInstance();
        /* Stripe Configuration variable will become available here */
        // Make Stripe API Callout to create a Customer in Stripe using Http Class
    }
}

				
			

In the above code, we have implemented the Singleton Pattern and now the instance will only be initialized once.

Check list

  • Define a private static attribute in the “single instance” class.
  • Define a public static accessor function in the class.
  • Do “lazy initialization” (creation on first use) in the accessor function.
  • Define all constructors to be protected or private.

Resources

Amit Singh
Amit Singhhttps://www.pantherschools.com/
Amit Singh aka @sfdcpanther/pantherschools, a Salesforce Technical Architect, Consultant with over 8+ years of experience in Salesforce technology. 21x Certified. Blogger, Speaker, and Instructor. DevSecOps Champion
Share this

Leave a review

Excellent

SUBSCRIBE-US

Book a 1:1 Call

Must-read

How to Utilize Salesforce CLI sf (v2)

The Salesforce CLI is not just a tool; it’s the cornerstone of development on the Salesforce Platform. It’s your go-to for building, testing, deploying, and more. As one of the most important development tools in our ecosystem

Save the day of a Developer with Apex Log Analyzer

Table of Contents What is Apex Log Analyzer? Apex Log Analyzer, a tool designed with Salesforce developers in mind, is here to simplify and accelerate your...

Salesforce PodCast

Introduction Hey Everyone, Welcome to my podcast, the first-ever podcast in India for Salesforce professionals. Achievement We are happy to announce that we have been selected as Top...

Recent articles

More like this

LEAVE A REPLY

Please enter your comment!
Please enter your name here

5/5

Stuck in coding limbo?

Our courses unlock your tech potential