5

I have a situation where I have three requirements:

  1. Lazy initialization - don't create the collection until asked for it
  2. Caching - keep the collection in memory on the object
  3. Reinitialization - be able to reinitialize the collection when desired, instead of simply getting the existing results.

This is simply an optimization inside a single class - it is not loading anything from a database and ideally I'd like just a good method design pattern for this, not a multiple-class design.

Usually for lazy initialization I'd have this:

Collection getCollection() {
    if (collection != null) {
         // generate and set collection
    }
    return collection;
}

But now I'm having trouble deciding on the best way to provide for reinitialization of a fresh collection and getting that collection. A fresh boolean parameter would work, but adding a parameter to a getter doesn't seem to feel right (maybe that's the Java in me talking — I could be convinced).

2
  • 1
    Warning--this isn't thread-safe! Apr 12, 2011 at 4:18
  • @Loren I suppose that sort of depends on the generate code. I could have specified that this object will only exist within the scope of one thread, though.
    – Nicole
    Apr 12, 2011 at 4:39

4 Answers 4

6

If you're limiting yourself to a single method call then I can't honestly imagine a parameterless solution that distinguishes between retrieving the cached value and a reinitialized value.

Every cache I've seen uses one of the following patterns:

  • An Invalidate or Expire method that flags the value for reinitialization on the next lookup;

  • A boolean or enumeration parameter, such as the one you've ruled out;

  • A separate reinitialization method, i.e. getNewCollection.

I do think it must be the Java in you talking, because in other languages I'm very much accustomed to passing parameters in cache lookups - in some cases one of the parameters may even be an anonymous method or function pointer telling the cache how to get the value.

When designing a cache based on deferred initialization, you'll almost certainly also want to have method overloads that take parameters for priority and/or expiration, since there's no longer any Put or Store method to hold them. So, I think the notion of a parameterless lazy-loaded lookup method with optional refresh is pretty much out the window.

If you're uncomfortable with it being a getter, then just give it a different name like Load or Lookup.

P.S. I realize you may not actually be designing a cache here, but the principles still apply; you don't want to have something that acts like a cache internally but doesn't provide cache semantics. That would just lead to headaches.

1
  • Clarified question: not entirely opposed to parameters, also not completely attached to the idea of a combined method call. (+1, good summary of the options)
    – Nicole
    Apr 12, 2011 at 2:51
1

I would add an extra method instead of passing a boolean parameter:

Collection getFreshCollection()
{
   collection = null;

   return getCollection();
}
0

It may not be worth it in this case, but you could have a little class that hangs onto the collection and has two (public) methods: one for getting the cached value, and one for getting an updated/recomputed value. Both methods would probably have to have the lazy initialization code in them, unless you know for sure which one will get called first.

0

I would look at Aspect Oriented Programming (AOP). Caching is a fairly common use of AOP, and java has a pretty nice AOP tool called AspectJ.

It will help you keep your caching concerns separate from the entity or persistence concerns.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.