Lazy Load
An object that doesn't contain all of the data you need, but knows how to get it.
class Supplier... public List getProducts() { if (products == null) products = Product.findForSupplier(getID()); return products; }
As you load data from a database into memory it's handy to design things so that as you load an object of interest, you also load the objects that are related to that object. This makes loading easier on the developer using the object, who otherwise has to explicitly load all the objects they need themselves.
However if you take this to its logical conclusion, you reach the point where loading one object can have the effect of loading a huge amount of other related objects into the system, something that hurts performance when only a few of the objects are actually needed.
A Lazy Load interrupts this loading process for the moment, leaving a marker in the object structure so that if the data is needed it can be loaded only then. As many people know, if you're lazy about doing things you'll win when it turns out you don't need to do them at all.
How it Works
There are four main ways you can implement Lazy Load: lazy initialization, virtual proxy, value holder, and ghost.
Lazy initialization[Beck-patterns] is the simplest one to do. The basic idea is that every access to the field checks first to see if it's null. If it's null it calculates the value of the field before returning the field. To make this work you have to ensure that the field is self-encapsulated; meaning that all access to the field, even from within the class, is done through a getting method.
Using a null to signal a field that hasn't been loaded yet works well, unless null is a legal value for the field. In this case you either need something else to signal the field hasn't been loaded, or to use a Special Case for the null value.
Using lazy initialization is simple, but it does tend to force a dependency between the object concerned and the database so it works best for Active Record, Table Data Gateway, and Row Data Gateway. If you're using Data Mapper you'll need an additional layer of indirection. You can obtain this by using a virtual proxy[Gang of Four]. A virtual proxy is an object that looks like the object that should be in the field, but actually doesn't contain anything. Only when one of it's methods is called does it load the correct object from the database.
The good thing about a virtual proxy is that looks exactly like the object that's supposed to be there. However it isn't so you can easily run into a nasty identity problem. Often the virtual proxy is a different object to the real object. Furthermore you can have more than one virtual proxy for the same real object. All of these will have different object identities, yet they represent the same conceptual object. At the very least you have to override the equality method and remember to use it instead of an identity method. But without that, and discipline, you'll run into some very hard to track bugs.






