Monthly Archives: April 2009

The Lazy Reference Accessor Pattern (example in ActionScript3)

When de-serializing objects from SQL storage, the references between the objects appear as foreign key values. Once each object is initialized with its data, one could immediately use the foreign key values to lookup the other objects and store references to them. Even if the objects do not have reciprocal or circular references, loading the types of objects in the correct sequence — target objects loaded before references to those targets — is fussy and creates a dependency between the schema and the loader. One can wait to do these lookups until after all of objects load, but that implies that one will load all objects.

If one goes a step further, the references can remain null until someone actually needs them. Moreover, an object can supply the foreign references (key values) without retrieving the referenced object at all. This can avoid performing the lookup at all even if the object is re-serialized (which requires those foreign key references).

The pattern stores both the reference to the object and the foreign key value that identifies the object (i.e. its key) and uses accessors and mutators to ensure that only one of the two values is active at a time. The referenced-object accessor do the actual lookup if the object reference does not already exist, and the foreign key mutator will store the new foreign reference key value and clear any existing reference object rather than doing a lookup immediately. Note that both mutators optimize by checking to see if the current value already matches the desired value.


<rant>

The optimization of checking to see if the current value already matches the desired value is common in Delphi classes; I don’t know why ActionScript3 classes do not do this as a Best Practice. The [Bindable] metatag’s implicit accessors and mutators do this sort of optimization; why not do it when coding by hand?

</rant>


private var _otherObjectId : uint = 0;
private var _otherObject : OtherObjectVO = null;
public function get otherObjectId () : uint
{
    if (_otherObject != null)
        return _otherObject.id;
    else
        return _otherObjectId;
}

public function set otherObjectId(value : uint) : void
{    // use the accessor, not the variable
    if (this.otherObjectId != value)
    {
         _otherObjectId = value;
        _otherObject = null;
    }
}

public function get otherObject() : OtherObjectVO
{
    if ((_otherObject == null) && (_otherObjectId != 0))
        _otherObject = goGetTheOtherObject(otherObjectId);

    return _otherObject;
}

public function set otherObject(value : OtherObjectVO) : void
{
    if(_otherObject != value)
    {
        _otherObject = value;
        _otherObjectId = 0;
    }
}

While the otherObject() accessor prevents unnecessary lookups during the object’s de-serialization, the otherObjectId() accessor prevents an unnecessary lookup at the end of an object’s life when it’s being serialized.

With objects that have many references that its client might not every need (e.g. configuration objects), the Lazy Reference Accessor pattern can eliminate unnecessary object loading, saving memory, time, and data access.