Refactor the cache algorithm to use a decorator pattern instead.

This makes it easier to combine different cache types. For example, DiskCache + LruCache, or MemoryCache + LruCache.