Pierre Greborio.NET

Talking about .NET world

Lazy Initialization

One of the most critics about Object Orientation for real world projects I get during the speaks is: OOP isn't performant. Considering a very simple example where a class Customer contains a list of classes Order. For the best OO philosophy we should have three types: Customer representing a single customer entity, Order which is an order entity and an Orders class wich is a list of Order entities (strongly typed collection of Order types).

Normally, all objects are, in some way, mapped over a relational database and when the consumer wants some information about a customer, they are loaded from the database.

The standard .NET way (many devs adopt this one) is to use a DataSet with two DataTable with a relation. The OOP way should be to load all informations from the database (maybe using a ORM tool) and expose them through it's object model.

This approach can provide some performances drawback when we load all informations (for all entities) at the same time (object creation time), especially if we need only some info from the customer and not it's orders.
Another approach consits in loading the deep information (in this sample the Orders) only on demand, as the Lazy Initialization pattern suggests.

Considering the following pseudocode:

public class Customer {
  // all code here
  public Orders CustomerOrders;

  public void Load(int customerID) {
    // Load the customer from DB and also it's orders (ie. Orders.Load(customerID))
  }
}

Can be refactored to:

public class Customer {
  // all code here
  private Orders _customerOrders = null;

  public Orders CustomerOrders {
     get
    {
         if(_customerOrders == null)
           _customerOrders = Orders.Load(customerID);
         return _customerOrders;
    }
  }

  public void Load(int customerID) {
    // Load only the customer from DB 
  }
}

As we can see the orders are loaded from the database only if really needed. This pattern is applicable to all objects where the creation of some instance variables cost either in terms of time or memory and they may never be used. This pattern is used as basis of a large numer of aother patterns, such as Singleton.

The sample above isn't thread safe but I will talk about it another time. Stay tuned :-)

Comments

Andres Aguiar said:

The thing is that sometimes you want lazy loading and sometimes you want eager loading. Lazy loading could imply more than eager loading. So, if you need _all_ the data it's better to use eager loading. If you need just the Customer object, it's better to use Lazy Loading.

The point is that is the one who is using the class the one who should decide which approach is better to the scenario, and it's not easy to design a OO model that lets you decide in runtime if you want eager loading or lazy loading.
# July 7, 2003 6:23 AM

Pierre Greborio said:

Yes, it depends of the context of the application. Nevertheless the sample can is just a sample of the pattern application even if it contains some other concepts (such as eager loading as you said).

You can decide for the user of the class depending on the relationship between the classes you implemented. If the relationship is aggregation you decide for him, whereas if the relationship is association he decide for you.

This sample works fine in the first case, whereas in the second one it don't.

Thanks for the feedback
Pierre
# July 8, 2003 10:08 PM

Artyom said:

it seems everything fine with Lazy Loading...
except scenario:
you populate data in other layer than presentation (ASP.NET for example) and then trasport data over wire (.NET remoting for example). Lazy load just kills your customers when they wait for ages :)
# September 3, 2003 5:28 AM

Pierre Greborio said:

That is a scenario where you should adopt other patterns: facade and proxy.
# September 3, 2003 12:08 PM

Artyom said:

in case of facade there is daunting task to desribe with some kind of schema or object model which navitabale object graph paths should be retrieved. thats essentially what I developing right now.
# September 4, 2003 2:42 AM