NOTA : sentiti libero di modificare il titolo se è leggermente diverso dalla mia domanda.
In una delle nostre applicazioni, stiamo mantenendo molte proprietà all'interno dell'oggetto Instance. Ovviamente è mantenuto come Map<K, Map...>
. Esistono pochi oggetti di istanza che contengono diversi tipi di proprietà.
Ad esempio
1) AppPropertyReader - Map<String, String>
2) SMSPropertyReader - Map<UUID, Map<SMSType, String>> // SMSType is enum
3) PropertyReader - Map<UUID, Map<String, Map<String, String>>>
e alcuni altri ...
Quindi per ogni classe di lettori, devo definire getter (s) e setter. A seconda del numero di tipi annidati, è necessario introdurre nuovi getter. Ma sento che è un po 'più povero / brutto (qualcosa che non posso esprimere chiaramente) per duplicare il getter & altri codici essenziali in ogni classe di lettori. Quindi ho scritto tre classi generiche per gestire fino a tre mappe (come definite nella classe PropertyReader).
Titolare della mappa di base
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();
}
}
Titolare della mappa nidificato
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);
}
}
Detentore della mappa nidificata profonda (non è sicuro se possa essere espresso come "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);
}
}
Quindi le mie classi di lettori di proprietà possono estendersi come
class AppPropertyReader extends CommonPropertyHolder<String, String>
class SMSPropertyReader extends CommonMapPropertyHolder<UUID, SMSType, String>
class PropertyReader extends CommonMultiMapPropertyHolder<UUID, String, String, String>
Funziona in modo incredibilmente perfetto.
Nella vista normale, queste classi generiche non faranno molta differenza. Ma se guardi come ogni classe fa riferimento a super metodi e variabili, saprai quanto è bella.
Se desidero introdurre un altro PropertyReader, devo semplicemente estendere la classe generica appropriata senza scrivere alcun codice diverso dalla dichiarazione della classe.
Ecco le mie domande.
1) Dal momento che sale fino a 3 livelli più profondi per la maggior parte dei generici parametrizzati, influenzerà l'esecuzione runtime ..? (Ho letto da qualche parte in StackOverflow che la profondità fino a 5 livelli non ha un impatto notevole sulle prestazioni.) Ma, dal momento che ogni classe estesa è generica, ci sarà un impatto sulle prestazioni ..?
2) Prima di inventare queste 3 classi generiche, ho cercato di raggiungere qualsiasi livello di mappe nidificate con una sola classe generica. Ma non riesco a trovare alcuna soluzione implementabile. È possibile implementare solo una singola classe generica in grado di gestire qualsiasi livello di profondità ...? (Naturalmente tutto deve essere ricorsivo se implementabile)