2016-07-02 9 views
0

私はプログラムのために多相ExportRuleシステムをセットアップしようとしていますが、その上にExportRuleが定義されている設定ファイルから目的のExportRuleを構築する方法がわかりませんファイルを文字列で渡します。文字列の識別子からの多態的な構造

私はこのような何かを探していました:

ExportRulesは(ExportRuleを拡張)実際の.classに文字列をマッピング列挙され、その後に静的fromFileConfiguration()ファクトリメソッドを呼び出します
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); 
} 

このようなファイルからExportRuleを生成します。

exportRule: nameOfExportRule 
//all the configurationstuff for the rule 

私がいる問題は、それが静的メソッドであるため、Javaが、私はそれはです保証することはできませんとして実際にfromFileConfiguration()メソッドを呼び出す方法ですEを介した存在xportRuleインターフェイス

このようなことを達成するためのクリーンな方法はありますか、各ExportRuleの列挙型でswitch文を実行する必要はありますか?

編集:

ありがとうございますglee8e!

ここに私の列挙です:

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; 
} 

} 

答えて

1

多型は、少なくともJavaで、静的なものはなく、インスタンスメソッドのためではありません。あなたのfromFileConfiguration抽象インスタンスメソッドを作成し、個々の定数でそれをimplememt:

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

} 

は、Javaの列挙型を覚えても、通常のクラスです。インタフェースを実装したり、抽象メソッドなどを持たせることができます。あなたは非Enumスーパークラスと非プライベートコンストラクタを持つことはできません。

PS:Java8の場合、この列挙は、1つの抽象メソッドを持っているので、あなたの代わりにこのようなサブクラスの多くを作るのFunctionを使用することができます。

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); 
    } 

} 

これは古典的な多型ではありませんがジョブを実行し、生成されたスクラップを減らします。

+0

これは、各ExportRuleがそれ自身のクラスではなく列挙型で完全に定義されることを要求していますか? - My ExportRuleクラスには、設定ファイルからの構築と実際のルール処理の両方のロジックがあります。 – CrypticCabub

+0

いいえ、セットアップはブラックボックス内で行われます。ブラックボックスとは、クライアントがExportRuleがどのように組み立てられているかを知りませんが、最終的にどのようなExportRuleを取得するかを意味します。 ExportRuleクラスにロジックを委任することを含め、ここで好きなことをすることができます。 – glee8e

+0

私はどのように私のfromConfigurationFile()メソッドに実際に構築を委任するのですか?それはJavaが明示的にクラスを知らなくても私をターゲットにさせない静的なコンストラクタなのでしょうか? – CrypticCabub

関連する問題