NOTE : Feel free to edit the title if it is somewhat different than my question.
In one of our application, we are maintaining a lot of properties inside Instance object. Obviously it's maintained as Map<K, Map...>
. There are few instance objects which holds different types of properties.
For example
1) AppPropertyReader - Map<String, String>
2) SMSPropertyReader - Map<UUID, Map<SMSType, String>> // SMSType is enum
3) PropertyReader - Map<UUID, Map<String, Map<String, String>>>
and a few more...
So for every reader class, I've to define getter(s) and setter. Depending upon the no of nested types, new getters have to be introduced. But I feel that it's somewhat poorer / uglier (something which I can't express clearly) to duplicate the getter & other essential codes in every reader class. So I've written three generic classes for handling upto three maps (like defined in PropertyReader class).
Base Map holder
import java.util.HashMap;
import java.util.Map;
public abstract class CommonPropertyHolder<K, V> {
protected Map<K, V> properties;
public CommonPropertyHolder() {
init();
}
protected void init() {
properties = new HashMap<K, V>();
}
public Map<K, V> getProperties() {
return properties;
}
public V getProperty(K key) {
return properties.get(key);
}
protected void setProperty(K key, V value) {
properties.put(key, value);
}
protected void clear() {
init();
}
}
Nested Map holder
import java.util.HashMap;
import java.util.Map;
public class CommonMapPropertyHolder<T, K, V> extends CommonPropertyHolder<T, Map<K, V>> {
public V getProperty(T type, K key) {
Map<K, V> properties = getProperty(type);
if( properties == null ) return null;
return properties.get(key);
}
protected void setProperty(T type, K key, V value) {
Map<K, V> properties = getProperty(type);
if( properties == null ) {
properties = new HashMap<K, V>();
setProperty(type, properties);
}
properties.put(key, value);
}
}
Deep Nested Map holder (not sure about if it can be expressed as "Deep Nested")
import java.util.HashMap;
import java.util.Map;
public class CommonMultiMapPropertyHolder<T, PK, K, V> extends CommonMapPropertyHolder<T, PK, Map<K, V>> {
public V getProperty(T type, PK parentKey, K key) {
Map<K, V> properties = getProperty(type, parentKey);
if( properties == null ) return null;
return properties.get(key);
}
protected void setProperty(T type, PK parentKey, K key, V value) {
Map<PK, Map<K, V>> mapProperties = getProperty(type);
if( mapProperties == null ) {
mapProperties = new HashMap<PK, Map<K, V>>();
setProperty(type, mapProperties);
}
Map<K, V> properties = mapProperties.get(parentKey);
if( properties == null ) {
properties = new HashMap<K, V>();
mapProperties.put(parentKey, properties);
}
properties.put(key, value);
}
}
So my property reader classes can extend like
class AppPropertyReader extends CommonPropertyHolder<String, String>
class SMSPropertyReader extends CommonMapPropertyHolder<UUID, SMSType, String>
class PropertyReader extends CommonMultiMapPropertyHolder<UUID, String, String, String>
This works amazingly perfect.
In normal view, these generic classes won't be much a difference. But if you look at how each class refers super methods and variables, you will know how beautiful it is.
If I ever want to introduce another PropertyReader, I just have to extend the appropriate Generic class without writing any code other than class declaration.
Here are my questions.
1) Since it goes upto 3 levels deeper for most parameterized generics, will it affect the runtime performace..? (I read somewhere in stackoverflow that depth upto 5 levels don't have noticable performance impact.) But, since every extended class is generics, will there be a performance impact..?
2) Before I came up with these 3 generic classes, I tried to achieve any level of nested maps with just a single generic class. But I can't come up with any implementable solution. Is it possible to just implement a single generics class which can handle any levels of depths..? (Ofcourse everything have to be recursion if implementable)