Use lazy initialization pattern

From CSSEMediaWiki
(Difference between revisions)
Jump to: navigation, search
(Lazy initialization)
(Lazy initialization)
Line 12: Line 12:
 
* The value can easily be reset to its default value independently of other variables just by calling the setter with a null value.
 
* The value can easily be reset to its default value independently of other variables just by calling the setter with a null value.
  
There is one major risk in this approach in that accidental passing of a null value to the setter will not cause the program to fail gracefully; it will instead cause the attribute to be reset to it's default value the next time it is accessed.
+
There is one major risk in this approach in that accidental passing of a null value to the setter will not cause the program to fail gracefully; it will instead cause the attribute to be reset to it's default value the next time it is accessed. Also having the getter change the state of the variable it gets even if only to initialise it breaks the [[Keep_accessors_and_mutators_separate|Keep accessors and mutators separate]] maxim, and can not be considered thread safe.
  
 
===Explicit initialization===
 
===Explicit initialization===

Revision as of 02:41, 14 October 2009

Lazy initialization is the process of delaying the creation of an object or initialization of its attributes until it is needed. This avoids expensive operations for objects that may not be used. The Use Lazy Initialization Pattern is useful in situations where we want to set an initial or default value for a state variable in a way that retains the most flexibility possible. Lazy initialization is often used with the factory pattern and object pool pattern.

Contents

The Approach

There are two main ways to set initial, default values of state variables. These are explicit initialization and lazy initialization.

Lazy initialization

Lazy initialization is done in a getter method if the state variable has not been set to a value. There are 3 benefits to this approach:

  • It provides a suitable place for the value to be set because it is uncluttered by other variables and other forms of initialization.
  • If the variable is never accessed, then the overhead of initialization will not take place.
  • The value can easily be reset to its default value independently of other variables just by calling the setter with a null value.

There is one major risk in this approach in that accidental passing of a null value to the setter will not cause the program to fail gracefully; it will instead cause the attribute to be reset to it's default value the next time it is accessed. Also having the getter change the state of the variable it gets even if only to initialise it breaks the Keep accessors and mutators separate maxim, and can not be considered thread safe.

Explicit initialization

Explicit initialization involves adding an initialize() method to the class other classes who create instances of this object now have a responsibility to call the initialize method before using the object. This approach can provide sightly more efficient objects due to the lack of checking for null on each access of the variable but it also has some undesirable side effects:

  • Variables may be set to have non-trivial values (values that take some calculation to derive) and then never be used.
  • A subclass can override its superclass version of explicit initialization in one of two ways: Firstly, by calling the initialize() method from the superclass and adding extra behaviour, which can possibly lead to setting the variable to have the same value multiple times. Secondly, the subclass could re-write the initialize() method completely which can make the subclass vulnerable to missing changes that might be made to the superclass in the future.
  • It adds another place where variables are accessed directly. This can expose them to problems when implementation decisions are changed in the future. If setter methods are used instead of directly referencing the variable in order to avoid the problem mentioned, this forces default settings and explicit settings to be treated the same. This could be bad if the setter methods have side effects.

The most significant reason that one would use explicit initialization is efficieny of execution.

A Solution

Whenever you need to set initial, default values for state variables use lazy initialization.

If a variable needs to be reset to its default value for future use it is best to reset it by calling the setter method with null as the argument. This avoids initialization overhead if the value is not needed again.

one way of doing this without creating the extra overhead of testing for initialisation in every get method is:

     public SomeType getSomeValue(){
           try{
                  return someValue.getResult();
                } catch( NullPointerException e){
                    someValue.initalise();
                    return someValue.gerResult();
                }
     }

See also

Personal tools