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 its pretty easy and possible with Apex. Though there can be different strategies to implement singleton in Apex (inspired from my Java days learning). Before that following are the prerequisite to make a class Singleton.
There can be a static public method in class that returns the “Single” instance. Popular names to it are “self()” and “getInstance()” OR one can declare a public static property with only public get accessor and private set accessor. We will show this in a while.
Constructor should have 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 for simple Apex Singleton strategy. I said its 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 Simple Apex singleton strategy is its not meant to be used in case Singleton initialization requires some DML code to execute. For that scenario we need to setup the class 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 testmethods are added at end in each Singleton sample, this also shows how to use Singleton in client Apex Code.
Still if you feel some gap or have some queries, please feel free .. 🙂
Comments (6)
Anonymoussays:
March 9, 2010 at 2:04 pmGood example of singleton in apex. This is similar to the standard Singleton pattern. But the interesting part about singleton is the lifetime/visibility of the singleton object. In java for example, its per class loader (not even JVM). So each web-app in a container might have its own singleton instance. Curious to know, how this is handled on Salesforce platfrom.
Anonymoussays:
March 9, 2010 at 2:16 pmStatic is not really the Java style “static” in Apex. Because of multi-tenant nature of force.com, all the classes are cached for a limited time-period, mostly for Visualforce-Controller(request) scope. I said controller scope, because the same controller is available for multiple requests(ajax) until the page is not refreshed and the same is the life of a static variable class.Even the same applies for static for triggers etc in Apex. The static is available for a single thread of execution after that its dumped. I got this is salesforce docs for static ————————————–“Static variables are only static within the scope of the request. They are not static across the server, or across the entireorganization.Use static variables to store information that is shared within the confines of the class. All instances of the same class share asingle copy of the static variables. For example, all triggers that are spawned by the same request can communicate with eachother by viewing and updating static variables in a related class. A recursive trigger might use the value of a class variable todetermine when to exit the recursion.”————————————–So the singleton is per request Singleton. Nice catch 🙂
Anonymoussays:
May 8, 2010 at 4:15 pmIf you'd like to extend the scope beyond the current user/request check out the Custom Settings feature. API Info from the Apex documentation:http://www.salesforce.com/us/developer/docs/apexcode/index_Left.htm#StartTopic=Content/apex_methods_system_custom_settings.htm
Anonymoussays:
May 10, 2010 at 9:36 am@mtb Apex Custom Settings give a single cached access to some central configuration type data. So your statement is true in that regard, but that is not a true Singleton for us from programming standpoint, its more of a central CACHE. The post explains a generic way to achieve Singleton in Apex programming language. A good example can be some DATA + OPERATION required on a single instance. Custom Settings will fail on that.
Anonymoussays:
May 26, 2010 at 11:46 pmIs there any way in Apex to define a destructor for a singleton that would reliably execute DML?What I'm thinking is that multiple triggers may fire and all want to update a single object – could you use a singleton to share that object data, and put the update call in the destructor for the singleton?
Anonymoussays:
May 27, 2010 at 4:56 am@LarkinFor a scenario where multiple triggers will fire and try updating a single object, I would suggest trying to load that Sobject using SOQL “FOR UPDATE” construct. This locks the sobject and will avoid any race condition and multi-threading issues. Here is a link that explains this http://www.salesforce.com/us/developer/docs/apexcode/Content/langCon_apex_locking_statements.htmSingleton wouldn't work here, because static is per execution Thread, not a Java like static where a static object is available across threads. So if two triggers are executing in parallel then each will have its own copy of Singleton.