HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaModerate

A generic cache object

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
genericobjectcache

Problem

I have a "generic" cache object:

public class Cache {

    private static final Map cacheMap = new HashMap<>();

    public static ICacheable getCacheableElement(Class cacheableElementClass, Object... params) {
        ICacheable cacheableElement = cacheMap.get(cacheableElementClass);
        if (cacheableElement == null) {
            cacheableElement = addIfNotExists(cacheableElementClass, params);
        }
        return cacheableElement;
    }

    private static ICacheable addIfNotExists(Class cacheableElementClass, Object... params) {
        ICacheable cacheableElementAdded;

        if (cacheableElementClass.equals(SourceCode.class)) {
            cacheMap.put(cacheableElementClass, new SourceCode((String) params[0]));
        } else if (cacheableElementClass.equals(SymbolTable.class)) {
            cacheMap.put(cacheableElementClass, new SymbolTable());
        } else {
            // Error!
            throw new NullPointerException();
        }
        cacheableElementAdded = cacheMap.get(cacheableElementClass);
        return cacheableElementAdded;
    }
}


The Cache's responsibility is cache any kind of object. For that reason, I have the method's param params (I need to find a better name). params is for those objects which need a param for its creation. For example:

public class SourceCode implements ICacheable {

    private String sourceCode;
    public static final Character EOF = '#';

    public SourceCode(String sourceCode) {
        this.sourceCode = sourceCode.toUpperCase() + EOF;
    }
}


As you can see, SourceCode needs a String param (sourceCode) for its creation.

In some part of the code, I fill the cacheMap... In the case of the SourceCode:

cacheMap.put(cacheableElementClass, new SourceCode((String) params[0]));


Here is my problem. As you can see, I create the SourceCode object with the first element of params array (remember the varargs in the above method's signature). IMHO, this is not

Solution

I have a "generic" cache object:

That's actually pretty non-generic. Especially, Class is a raw type.

private static final Map cacheMap = new HashMap<>();


Moreover, static mutable state is nearly always wrong. Use an instance variable and if you really have to a static instance of Cache.

It's also strange to restrict the keys and values like this. Compare to Guava Cache.

Especially restricting the values to some ICacheable sounds wrong.


The Cache's responsibility is cache any kind of object.

As long as it's ICacheable???


Here is my problem. As you can see, I create the SourceCode object with the first element of params array (remember the varargs in the above method's signature). IMO, this is not a clean solution, because some objects will use the params array (SourceCode), and others won't use it.

I'm rather lost what it's all about. If there's a params array, it sounds OK to me to use just a part of it. Not using it at all is a special case as it's like using a subarray of zero length.

Maybe your single cache should be multiple caches, one per class? See also ClassToInstanceMap.

Code Snippets

private static final Map<Class, ICacheable> cacheMap = new HashMap<>();

Context

StackExchange Code Review Q#94333, answer score: 11

Revisions (0)

No revisions yet.