What is lazy initialization of objects? How do you do that and what are the advantages?
In general computing terms, 'lazy evaluation' means to defer the processing on something until you actually need it. The main idea being that you can sometimes avoid costly operations if you turn out to not need it, or if the value would change before you use it.
A simple example of this is System.Exception.StackTrace. This is a string property on an exception, but it isn't actually built until you access it. Internally it does something like:
String StackTrace{
get{
if(_stackTrace==null){
_stackTrace = buildStackTrace();
}
return _stackTrace;
}
}
This saves you the overhead of actually calling buildStackTrace until someone wants to see what it is.
Properties are one way to simply provide this type of behavior.
Lazy Initialization is the concept of deferring object creation until the object is actually first used. If used properly, it can result in significant performance gains.
Personally, I've used Lazy Initialization when creating my own hand-rolled ORM in .NET 2.0. When loading my collections from the database, the actual items in the collection were lazy initialized. This meant that the collections were created quickly, but each object was loaded only when I required it.
If you're familiar with the Singleton pattern, you've probably seen lazy initialization in action as well.
public class SomeClassSingleton
{
private static SomeClass _instance = null;
private SomeClassSingleton()
{
}
public static SomeClass GetInstance()
{
if(_instance == null)
_instance = new SomeClassSingleton();
return _instance;
}
}
In this case, the instance of SomeClass is not initialized until it is first needed by the SomeClassSingleton consumer.
The database examples that have been mentioned so far are good, but it's not restricted to just the data access layer. You could apply the same principles to any situation where performance or memory can be a concern. A good example (although not .NET) is in Cocoa, where you can wait until the user requests a window to actually load it (and its associated objects) from the nib. This can help keep memory usage down and speed up the initial application load, especially when you're talking about things like Preferences windows that won't be needed until some later time, if ever.