c.Lazy Load

  1. Motivation

    1. To defer the loading of actual data till it actually asked (on Demand)

  2. Summary

      1. A Lazy Load interrupts this loading process for the moment, leaving a marker in the object structure (for example page number or row count) so that if the data is needed it can be loaded only when it is used.

      2. 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.

  3. When to Use

      1. Adding Lazy Load does add a little complexity to the program, so prefer not to use it.

      2. It could be preferred when some fields of record set are too big for example LOB like media files.

  1. Implementation

      1. There are four main ways you can implement Lazy Load: lazy initialization, virtual proxy, value holder, and ghost.

        1. Lazy initialization

          1. The basic idea is that every access to the field checks first to see if it's null. If so, it calculates the value of the field before returning the field.

          2. Using lazy initialization is simple, but it does tend to force a dependency between the object and the database. For that reason it works best for Active Record, Table Data Gateway, and Row Data Gateway.

          3. If you're using Data Mapper (165), you'll need an additional layer of indirection, which you can obtain by using a virtual proxy .

        2. A virtual proxy

          1. It is an object that looks like the object that should be in the field, but doesn't actually contain anything. Only when one of its methods is called does it load the correct object from the database.

          2. The bad thing is that you can easily run into a nasty identity problem. Furthermore you can have more than one virtual proxy for the same real object.

      1. Value Holder

          1. With domain classes you can get around these problems by using a value holder.

          2. In this case one object that wraps some other object. To get the underlying object you ask the value holder for its value, but only on the first access does it pull the data from the database.

          3. The disadvantages of the value holder are that the class needs to know that it's present and that you lose the explicitness of strong typing. You can avoid identity problems by ensuring that the value holder is never passed out beyond its owning class.

        1. Ghost

          1. A ghost is the real object in a partial state. When you load the object from the database it contains just its ID.

          2. Whenever you try to access a field it loads its full state. Think of a ghost as an object, where every field is lazy-initialized in one fell swoop, or as a virtual proxy, where the object is its own virtual proxy.

          3. If you use a ghost, you can put it immediately in its Identity Map . This way you maintain identity and avoid all problems due to cyclic references when reading in data.

  1. Related Patterns

      1. TODO

  1. Related Technologies

      1. TODO

  1. Specific Considerations

      1. Limitations of Lazy loading

        1. Inheritance often poses a problem with Lazy Load.

        2. Virtual proxies can suffer from the same problem in statically typed languages.

        3. Danger with Lazy Load is that it can easily cause more database accesses than you need.

        4. Often you'll run into situations where different use cases work best with different varieties of laziness. Some need one subset of the object graph; others need another subset. For maximum efficiency you want to load the right subgraph for the right use case.

        5. The way to deal with this is to have separate database interaction objects for the different use cases. Thus, if you use Data Mapper (165), you may have two order mapper objects: one that loads the line items immediately and one that loads them lazily. The application code chooses the appropriate mapper depending on the use case. A variation on this is to have the same basic loader object but defer to a strategy object to decide the loading pattern. This is a bit more sophisticated, but it can be a better way to factor behavior.

  1. References

    1. Overview Tutorials

        1. TODO

    2. Further References