2017-06-27 4 views
0

Ich habe ein Graph Objekte mit Knoten. Ich brauche Annotationsobjekte, die für jeden Knoten beliebige Eigenschaften enthalten. Wenn ein Knoten eine Eigenschaft vom Typ T hat, haben alle anderen Knoten eine Eigenschaft dieses Typs. Annotator-Objekt fügt der Anmerkung dann Eigenschaften hinzu. Dies hält mein Diagramm agnostisch. Es gibt Code zum Hinzufügen einer Eigenschaft eines bestimmten Typs zu einem Knoten und Code zum Abrufen einer Eigenschaft nach Typ.Java Graph Annotation Eigenschaften Muster

Hier ist der Code, den ich zur Zeit in meiner Annotation-Klasse haben:

private Map<Class<? extends Property>, Map<Node, Property>> properties; 

@SuppressWarnings("unchecked") 
public <T extends Property> T getProperty(Node node, Class<T> clazz) { 
    if (properties.containsKey(clazz)) { 
     return null; 
    } 
    return (T) properties.get(clazz).get(node); 
} 

public void addProperty(Node node, Property property) { 
    if (!properties.containsKey(property.getClass())) { 
     properties.put(property.getClass(), new HashMap<>()); 
    } 

    properties.get(property.getClass()).put(node, property); 
} 

Ich glaube, das funktioniert gut, aber die Generika, wie sie nur sein nicht so streng scheinen könnte. Gibt es ein eleganteres Muster, das ich verwenden könnte?

danke!

Antwort

0

Ich glaube, dass die Eigenschaften-Map die beste Problemumgehung ist, die Sie aufgrund Ihrer aktuellen Beschreibung haben könnten.

Dennoch, da Sie bereits die Class Instanz haben, können Sie es verwenden, um die Besetzung auszuführen der Warnung (ohne ausdrückliche SuppressWarnings Anmerkung) loszuwerden.

Es wäre so etwas wie dieses:

return clazz.cast(properties.get(clazz)); 

Wenn Sie eine zusätzliche Schutzschicht gegen NullPointerException s wollte man es in so etwas wie ändern könnte:

return clazz.cast(properties.getOrDefault(clazz, Collections.emptyMap()).get(node)); 

Dies würde Ihre komplette getProperty machen Methode etwas wie:

public <T extends Property> T getProperty(Node node, Class<T> clazz) { 
    return clazz.cast(properties.getOrDefault(clazz, Collections.emptyMap()).get(node)); 
} 

Beachten Sie, dass ein expliziter Cast mit Class.cast() einen ClassCastException wirft, wenn der Cast nicht gültig ist.

Auch vergessen Sie nicht, Ihre Argumente zu überprüfen:

public <T extends Property> T getProperty(Node node, Class<T> clazz) { 
    Objects.requireNonNull(node); 
    Objects.requireNonNull(clazz); // Or inline them in the return, albeit not so readable 
    return clazz.cast(properties.getOrDefault(clazz, Collections.emptyMap()).get(node)); 
} 
+0

Dank, Ill diese Verbesserungen machen! –