0

I was going through the articles on the Singleton pattern in apex and came up with an example that describes Early Initialization vs Lazy Loading in the Singleton pattern.

Early Initialization:

public with sharing class EagerInitializedSingleton {

//private static instance of the class
private static final EagerInitializedSingleton instance = new EagerInitializedSingleton();

//private constructor to avoid creating an instance anywhere outside of this class
private EagerInitializedSingleton(){}

public static EagerInitializedSingleton getInstance(){
    return instance;
}

}

Lazy Loading:

public with sharing class LazyInitializedSingleton {

//private static instance of the class
private static LazyInitializedSingleton instance = null;

//private constructor to avoid creating an instance anywhere outside of this class
private LazyInitializedSingleton(){}

public static LazyInitializedSingleton getInstance(){
    if(instance == null){
        instance = new LazyInitializedSingleton();
    }
    return instance;
}

}

My question is, does Early Initialization make sense in Apex as the class is loaded only when it is used or referenced? If so can experts give some example in apex where Early Initializations happens?

2 Answers 2

3

In Salesforce, all Apex state is created per request (per transaction) - there is no long-lived "application" scope. All static references live for the length of the transaction but are re-created per transaction.

So lazy loading is generally the way to go:

  • Means that initialization work is only done for the methods and properties that are touched in each loaded class rather than for everything in each loaded class
  • So makes your code a bit faster
  • So reduces governor limit consumption
  • So stops the debug logs being flooded with irrelevant initialization work that appears before the logs of interest

Pragmatically, add the lazy loading to significant intialization e.g. setting up a map with many entries or running significant code.

For properties, the get syntax keeps the lazy loading encapsulated e.g.:

private static Map<String, Object> ENUM_BY_NAME {
    get {
        if (ENUM_BY_NAME == null) {
            ENUM_BY_NAME = new Map<String, Object>();
            for (ConditionEnum e : ConditionEnum.values()) ENUM_BY_NAME.put(e.name().toLowerCase(), e);
            for (DestinationEnum e : DestinationEnum.values()) ENUM_BY_NAME.put(e.name().toLowerCase(), e);
            for (PropertyEnum e : PropertyEnum.values()) ENUM_BY_NAME.put(e.name().toLowerCase(), e);
            for (ProratedByEnum e : ProratedByEnum.values()) ENUM_BY_NAME.put(e.name().toLowerCase(), e);
            for (ShareClassEnum e : ShareClassEnum.values()) ENUM_BY_NAME.put(e.name().toLowerCase(), e);
        }
        return ENUM_BY_NAME;
    }
    set;
}
1
  • 1
    The other benefit here is that you can extend this pattern into a singleton-based dependency injection mechanism. The specific singleton implementation can be dictated via the setting of a StubProvider or switching out the specific class to be instantiated via Type.newInstance or JSON.deserialize.
    – Phil W
    Commented Dec 13, 2022 at 8:37
1

the decision to use early or lazy initialisation of a Singleton class should depend on the specific use case and the trade-offs involved. With early initialisation, the instance of the Singleton class is created when the class is loaded, even if it is not immediately needed. This can potentially lead to resource wastage, as the instance is created even if it is never used. On the other hand, lazy initialisation delays the creation of the instance until it is actually needed, which can help to conserve resources and improve performance.

Like we can use early initialisation for database utilities that will definitely be used and lazy for utilities that are used less frequent

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .