Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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

share|improve this question
Warning--this isn't thread-safe! – Loren Pechtel Apr 12 '11 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. – NickC Apr 12 '11 at 4:39
up vote 7 down vote accepted

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.

share|improve this answer
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) – NickC Apr 12 '11 at 2:51

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

Collection getFreshCollection()
   collection = null;

   return getCollection();
share|improve this answer

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.

share|improve this answer

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.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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