2016-07-02 17 views
0

Ich versuche, ein polymorphes ExportRule-System für mein Programm einzurichten, aber ich habe Probleme herauszufinden, wie ich die gewünschte ExportRule aus einer Konfigurationsdatei konstruiere, bei der die ExportRule oben definiert ist Datei über einen String.Polymorphe Konstruktion von String ID

Ich war auf der Suche, so etwas zu tun:

private ExportRule loadExportRule(String fileName) throws IOException, InvalidConfigurationException, FileNotFoundException{ 
    if(fileName == null) { 
     throw new NullPointerException("fileName cannot be null!"); 
    } 
    YamlConfiguration exportRuleConfig = new YamlConfiguration(); 
    exportRuleConfig.load(getFilePath(fileName)); 

    return ExportRules.fromString(exportRuleConfig.getString("exportRule")).fromYamlConfiguration(exportRuleConfig); 
} 

wo ExportRules eine ENUM einen String an den tatsächlichen .class- Abbildung ist (die ExportRule erstreckt) und dann eine statische fromFileConfiguration() Factory-Methode nennen würde erzeugen die ExportRule aus der Datei, die wie folgt aussieht:

exportRule: nameOfExportRule 
//all the configurationstuff for the rule 

Das Problem, das ich habe, ist, wie eigentlich die fromFileConfiguration() -Methode aufrufen, da es eine statische Methode ist und daher Java erlaubt mir nicht, es ist zu gewährleisten, Existenz über die E xportRule interface

Gibt es einen sauberen Weg, um so etwas zu erreichen, oder muss ich irgendeine switch-Anweisung in meiner enum für jede ExportRule machen?

bearbeiten:

Vielen Dank glee8e!

hier meine Enum:

public enum ExportRules { 
COMMENT_CONCAT("CommentConcat") { 
    @Override 
    public ExportRule fromFileConfiguration(FileConfiguration fileConfiguration) throws InvalidConfigurationException { 
     return CommentConcat.fromFileConfiguration(fileConfiguration); 
    } 
}; 

private String name; 

ExportRules(String name) { 
    this.name = name; 
} 

public abstract ExportRule fromFileConfiguration(FileConfiguration fileConfiguration) throws InvalidConfigurationException; 

public String getName() { 
    return name; 
} 

public static ExportRules fromString(String str) { 
    for(ExportRules rule : ExportRules.values()) { 
     if(str.equalsIgnoreCase(rule.getName())) return rule; 
    } 
    return null; 
} 

} 

Antwort

1

Polymorphismus ist nicht für statische Sachen, aber Instanzmethoden, zumindest in Java. Machen Sie Ihre fromFileConfiguration eine abstrakte Instanz-Methode, und implememt es in einzelnen Konstanten:

public enum ExportRules { 
    A_RULE { 
     @Override public ExportRule fromFileConfiguration(YamlConfiguration c) {...} 
    }, 
    //... 
    public abstract ExportRule fromFileConfiguration(YamlConfiguration c); 

} 

Denken Sie daran, Java Aufzählungen sind auch normale Klassen. Sie können Schnittstellen implementieren, haben abstrakte Methoden und so weiter. Sie können jedoch nicht eine Nicht-Enum Superklasse und einen nicht-privaten Konstruktor haben.

PS: Für Java8, da diese ENUM eine einzige abstrakte Methode hat, können Sie eine Function verwenden, anstatt eine Menge Unterklassen machen, wie folgt aus:

public enum ExportRules { 
    A_RULE((c) -> {//...}), 
    //... 
    private final Function<YamlConfiguration, ExportRule> func; 
    private ExportRules(Function<YamlConfiguration, ExportRule> fun) { 
     func = fun; 
    } 

    public ExportRule fromFileConfiguration(YamlConfiguration c) { 
     return func.apply(c); 
    } 

} 

Dies ist nicht klassische Polymorphismus, aber es erledigt den Job und reduziert Ausschuss.

+0

tut dies nicht, dass jede ExportRule vollständig in der Enum statt seiner eigenen Klasse definiert werden muss? - Meine ExportRule-Klasse verfügt über eine Reihe von Logik sowohl für die Konstruktion aus der Konfigurationsdatei und dann die eigentliche Regelbehandlung selbst. – CrypticCabub

+0

Nein, die Einrichtung erfolgt in einer Blackbox. Die Blackbox bedeutet, dass die Kunden nicht wissen, wie die ExportRule genau zusammengebaut ist, aber welche Art von ExportRule er am Ende bekommen wird. Sie können hier alles tun, was Sie möchten, einschließlich der Delegierung der Logik an die ExportRule-Klassen. – glee8e

+0

Also wie würde ich die Konstruktion tatsächlich an meine fromConfigurationFile() -Methode delegieren? wäre das nicht immer noch ein statischer Konstruktor, auf den Java mich nicht zielen lässt, ohne die Klasse explizit zu kennen? – CrypticCabub