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

Nicole
  • 28,111
  • 12
  • 95
  • 143

4 Answers4

7

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.

Aaronaught
  • 44,005
  • 10
  • 92
  • 126
  • 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 '11 at 02:51
1

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

Collection getFreshCollection()
{
   collection = null;

   return getCollection();
}
CodeART
  • 3,992
  • 1
  • 20
  • 23
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.

Randy Coulman
  • 246
  • 1
  • 3
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.

Brook
  • 1,835
  • 13
  • 17