Monday 14 August 2017

Singleton Design Pattern

Singleton design pattern is the simplest design pattern in Apex. By using this pattern we can initiate class instance only once.

The Singleton pattern attempts to solve the issue of repeatedly using an object instance, but only wishing to instantiate it once within a single transaction context. It's most common use is to create an object instance that's instantiated only once for the lifetime of that execution context. 

The Singleton design pattern allows Apex code to repeatedly reference an object instance in an optimal manner, whilst mitigating the impact of governor limits.

Problem:- This is one example of inefficient code where developer is initializing class every time  new record is getting inserted in contact object. This will cause an error when we try to insert more than 100 records.

Trigger

trigger AccountTrigger on Contact(before insert, before update) {
for(contact record : Trigger.new){
ContactFSRecordType rt = new ContactFSRecordType ();
....
}
}

Class

public class ContactFSRecordType {
public String id {get;private set;}
public ContactFSRecordType (){
// This could breach the governor limits on describes
// if a trigger is executed in bulk
id = contact.sObjectType.getDescribe()
.getRecordTypeInfosByName().get('Foo').getRecordTypeId();
}
}

Solution
  • Creating a class with a method that creates a new instance of the class if it doesn't already exist
  • If it already exists, then simply return a reference to that object

Trigger

trigger ContactTrigger on Contact(before insert, before update) {
for(Contact record : Trigger.new){
// Instantiate the record type using the singleton class
ContactFSRecordType rt = ContactFSRecordType.getInstance();
....
}
}


Singleton Class

public class ContactFSRecordType {
// private static variable referencing the class
private static ContactFSRecordType instance = null;
public String id {get;private set;} // the id of the record type
// The constructor is private and initializes the id of the record type
private ContactFSRecordType (){
id = contact.sObjectType.getDescribe()
.getRecordTypeInfosByName().get('Foo').getRecordTypeId();
}
// a static method that returns the instance of the record type
public static ContactFSRecordType getInstance(){
// lazy load the record type - only initialize if it doesn't already exist
if(instance == null) instance = new ContactFSRecordType ();
return instance;
}
}
In order to implement a Singleton pattern in Apex, the class must instantiate only a single instance and be globally accessible. It is implemented by:
Some important points from above example:- Constructor should be private so that it can not initialized outside getInstance
method. 

getInstance method will only initiate instance of class if it does not exist
The class defines a private, static instance of itself that can only be referenced
via the getInstance() static method.

The ID member stores the record ID of the record type and is initialized in the
constructor.

Reference

https://developer.salesforce.com/page/Apex_Design_Patterns

http://www.tgerm.com/2010/03/apex-implementing-singleton-design.html

http://www.oyecode.com/2012/12/implementing-singleton-design-pattern.html 

2 comments:

Please add your comments here