Implementing Singleton Design Pattern in Apex

Context You are building an application in Apex. You need a class that has only one instance, and you need to provide a global point of acce...

Context

You are building an application in Apex. You need a class that has only one instance, and you need to provide a global point of access to the instance. You want to be sure that your solution is efficient and that it takes advantage of Salesforce power design features. 

Implementation Strategy


Even though Singleton is a comparatively simple pattern, there are various tradeoffs and options, depending upon the implementation. The following is a series of implementation strategies with a discussion of their strengths and weaknesses.

Scenarios

Scenario 1 : Calling Global Describe only once 


Salesforce recommend to use  data structure effectively to bulkify the apex code. The Maps is super powerful data structure, are not just unique to Apex but maps are used in wide gamut of languages and with Apex, the maps play a key role to avoid SOQL calls and meeting governor limits 

Consider a situation where a developer design a  visual-force page and need to inspect custom object fields on set of events (page load). Salesforce provides describe () method to read the fields, but if we call describe method repeatedly, we again end up with memory in-efficient design. 

The effective way would be storing all describe methods results in a map and using one single map we can play around to meet our needs, and again we don't want to create map for every call, so we apply singleton pattern of storing data in map, meaning if we have map populated already, we will avoid re-populating it back which save another set of memory for us.

Here is how you can do it with simple piece of code, I believe code will give you better understanding




Scenario 2: Calling Trigger only once 

Let us consider a scenario when trigger do field update, and field call workflow and workflow on action do another field update which in result invoke trigger again. How do we stop this, to understand clearly please check out my previous article here and here for this kind of implementation in detail

Scenario 3: Understanding the pattern in better fashion by effectively improving Trigger code 

In the code below, I have written a code in for Trigger on Opportunity at before insert and update events and if you carefully notice I am creating an new instance (new object) of the class inside the for loop, which mean every time the trigger is invoked, I'll create an new object for the class OpportunityRecordType. This designwill work for some cases but in the case of bulk calls, this trigger will touch governor limit easily and clearly this code is not designed to handle bulk requests


Basic approach is use static variable, lets pause and talk quickly about static variables, what does the static variable do 

Static Variable - lets discuss what does this do 

  • Static can modify member and blocks 
  • Loaded when a class is loaded (introduced) to runtime environment
  • How long this last in Java ?  Life of JVM (Java Virtual Machine) can be days, weeks, months, 
  • What about Apex ? Life of Transaction would be just milliseconds 
  • Point is singleton is only a singleton within a transaction, which mean you wont get same instance in different transaction 
So lets add a property called instance to the code and then add design a method that take care that if the instance do exist, no new instance is created else new instance is created


Problem is fixed, now for each iteration of for loop, the constructor will called for method getInstance() which in-result for first iteration it creates an instance and for second iteration it grab the existing instance 



Should we stop here : Well no, because there no-code that confirm me for singleton pattern, reason why because there is no code confirming at line number (4) saying that if OpportunityRecordType.Instance() == null, then what should we do and we end up in same situation.


Let do some more modification, the problem is our instance is public, so lets make it private 



Should we be still satisfied - Although we fix the basic problem but the 'constructor' needs to be private too


This confirms that we have achieved singleton pattern. I believe this help you to understand how to apply singleton-pattern in Apex in wide capacities

PS :
    :Software Design Pattern by wikipedia 
    :OOPatterns
    :Abhinav Gupta on Singleton Pattern 
     

What Others Are Reading