I first heard the term, “lazy instantiation”, when I started working in iOS. I’d used the idea before, but didn’t have a name for it. The basic idea is to “[delay] the creation of an object, the calculation of a value, or some other expensive process until the first time it is needed.” (Wikipedia).
Here’s an example in Objective-C:
- (myClass *)myClass
{
if (!_myClass){
_myClass = [[myClass alloc] init];
[_myClass setUpMyClass]; // this method just loads sounds and some text
}
return _myClass;
}
Lately, it seems like all of my projects have needed to access third party APIs. I’ve been using lazy instantiation to combat unnecessarily calling the external resources. What follows is a simple example of some code for retrieving what’s currently playing on Rdio:
class RdioQueue
attr_reader :client, :venue
def initialize(client, venue)
@venue = venue
@client = client
end
def rdio_user
@rdio_user ||= self.client.get(:keys => self.venue.uid, :extras => "lastSongPlayed,lastSongPlayTime").values.first
end
def rdio_track
@rdio_track ||= self.rdio_user.lastSongPlayed
end
def rdio_track_start_time
@rdio_track_start_time ||= self.rdio_user.lastSongPlayTime
end
# ... other unrelated methods ...
end
This class is primarily used to retrieve album track information, all of which is handled through the call to Rdio’s user
API. Rather than making a separate call through the Rdio client each time information is needed, we just pass our messages through rdio_user
. Once it’s initially retrieved, the external call is never made again (thanks to the or-equal ||=
operator).
If we needed to perform an action against rdio_track
further down in our code, we would just call rdio_track
. There would be no need to first initialize rdio_user
, it all just happens “just in time”™. At this point, rdio_user
has its instance variable (ivar) set and further calls to rdio_user
return immediately, as do calls to rdio_track
.
Some care must be taken with lazy instantiation. If taken to an extreme, it will result in a Law of Demeter violation.
I am not presenting any hidden coding secrets or revelations. None of this is rocket-science, and it’s likely you’re already using lazy instantiation in a current project. Only, now you have a name for it.