Apex Design Patterns Series: The Singleton Pattern

AMIT SINGH
4 min readAug 17, 2022

--

INTRODUCTION

Apex allows us to develop any custom solution. 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

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 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 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 the 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 to 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.

CHECKLIST

  • 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

Software Developer by day & YouTube by night. Salesforce Architect || Salesforce MVP || Integration Expert