RSS Feed for This PostCurrent Article

Design Pattern in Java 101 - Lazy Load Part I

Download Sample Code

Lazy Load is one of the object relational behavioral patterns. With lazy load, an object does not contain all of the data you need but knows how to get it when it is needed. This pattern is commonly found in most of the OR mappers, e.g. Hibernate.

E.g. when you load the Product table, you may or may not want to load data from the Supplier table. Using Lazy Load pattern, you load data from Product table, and supplier data can be loaded when it is needed.

There are 4 main ways to implement Lazy Load, as described by Martin Fowler in the book Patterns of Enterprise Application.

lazy initialization
With lazy initialization, every access to the field is checked against a special value, e.g. null value. If the value is not found, then the object needs to perform some logic, e.g. lookup from database, before returning.

E.g.

import java.util.List;

public class Product {
    private List<Supplier> suppliers;

    /**
     * Lazy Load Pattern - Lazy Initialization
     * @return
     */
    public List<Supplier> getSuppliers() {
        if (suppliers == null) {
            // Connect to database to
            // retrieve the supplier list
        }
        return suppliers;
    }
}

virtual proxy
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.

E.g.

First, define a DomainObject

package virtualproxy;

public abstract class DomainObject {
}

Both Student and Course inherits DomainObject

package virtualproxy;

public class Course extends DomainObject {
    private Long id;
    private String name;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
package virtualproxy;

public class Student extends DomainObject{
    private Long id;
    private VirtualList courses ;

    public Student(Long id) {
        this.id = id;
    }

    public VirtualList getCourses() {
        return courses;
    }

    public void setCourses(VirtualList courses) {
        this.courses = courses;
    }
}

courses in Student is a VirtualList.

package virtualproxy;

import java.util.List;

public class VirtualList {
    private List<DomainObject> source;
    private VirtualListLoader loader;

    public VirtualList(VirtualListLoader loader){
        this.loader = loader;
    }

    public List<DomainObject> getSource() {
        if (source == null) source = loader.load();
        return source;
    }

    public int size(){
        return getSource().size();
    }

    public boolean isEmpty(){
        return getSource().isEmpty();
    }

    /////

VirtualListLoader is defined as below.

package virtualproxy;

import java.util.List;

public interface VirtualListLoader {
    List<DomainObject> load();
}

StudentMapper is as below.

package virtualproxy;

import java.util.ArrayList;
import java.util.List;

public class StudentMapper {

    public static class CourseLoader
               implements VirtualListLoader {
        private Long id;

        public CourseLoader(Long id) {
            this.id = id;
        }

        public List<DomainObject> load() {
            // Load the course using the
            // student id supplier. Now returning dummy
            List<DomainObject> courses =
                    new ArrayList<DomainObject>();
            Course c1 = new Course();
            c1.setId(1L);
            c1.setName("Mgmt");
            courses.add(c1);
            Course c2 = new Course();
            c2.setId(2L);
            c2.setName("IT");
            courses.add(c2);
            return courses;
        }
    }

    protected DomainObject doLoad(Long id) {
        Student result = new Student(id);
        result.setCourses(new VirtualList(new CourseLoader(id)));
        return result;
    }
}

To test it

package virtualproxy;

import java.util.List;

public class TestVirtualProxy {

    public static void main(String args[]){
        StudentMapper studentMapper = new StudentMapper();
        Student student = (Student)studentMapper.doLoad(1L);
        VirtualList courseVL = student.getCourses();
        List<DomainObject> courses = courseVL.getSource();
        for (DomainObject course: courses){
            Course c = (Course)course;
            System.out.println(c.getId());
            System.out.println(c.getName());
        }
    }
}

The output

1
Mgmt
2
IT

In the coming article I shall talk about value holder and ghost.


Trackback URL


1 Trackback(s)

  1. From Design Pattern in Java 101 - Lazy Load Part II | twit88.com | Jan 22, 2008

RSS Feed for This PostPost a Comment