Skip to content

Instantly share code, notes, and snippets.

@dhoechst
Last active December 23, 2015 12:39
Show Gist options
  • Save dhoechst/6636852 to your computer and use it in GitHub Desktop.
Save dhoechst/6636852 to your computer and use it in GitHub Desktop.
Trying to understand the singleton pattern and why some people consider it bad.
// from http://wiki.developerforce.com/page/Apex_Design_Patterns_-_Singleton
// What makes this a singleton pattern? Is it that it uses a private constructor?
public class AccountFooRecordType {
// private static variable referencing the class
private static AccountFooRecordType 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 AccountFooRecordType(){
id = Account.sObjectType.getDescribe()
.getRecordTypeInfosByName().get('Foo').getRecordTypeId();
}
// a static method that returns the instance of the record type
public static AccountFooRecordType getInstance(){
// lazy load the record type - only initialize if it doesn't already exist
if(instance == null) instance = new AccountFooRecordType();
return instance;
}
}
// My attempt at making it better.
// Instead of having a private constructor I just return the private variable after checking if it is null or not
public class AccountFooRecordType {
private static Id instance;
public static Id getInstance() {
if (instance == null) instance = Account.sObjectType.getDescribe()
.getRecordTypeInfosByName().get('Foo').getRecordTypeId();
return instance;
}
}
@dhoechst
Copy link
Author

So wouldn't the second one also be a singleton too, then? Line 8 also checks to see if it has been accessed and lazy loads.

@britishboyindc
Copy link

The second one is the easiest approach. But the second one is NOT a singleton pattern I believe, because no instance of the class is evert instantiated - you are calling a method on the class itself, not an instance of the class. Take a look at the Java docs for some more detailed explanation: http://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html

Because all objects in SF only persist for the length of the transaction (e.g. a trigger execution), you don't get any benefit from the singleton pattern as far as I know. Next time the trigger fires, you are going to have to instantiate again - so you might as well just call a static method to achieve the same thing. Where it makes sense is the example Matt referred to in his SE post - you are running a program with a framework that persists state, and a class should have one instance of a class running, but only ever one...

@dhoechst
Copy link
Author

Thanks! That's what I was thinking too. After some more reading this morning and watching the DF session on Apex patterns, I think I understand the difference. I actually am using the approach in the second one. One of my coworkers called it a singleton and that threw me off. What I really learned from all this is that static can actually persist through the entire transaction. I had always assumed you had to instantiate an object to get persistence.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment