2009-07-18 1 views
0

私はいくつかのクラスをいくつかの重いライブラリ(パーサー、タグ、その他のリソースなど)に渡って動作させます。これらのライブラリはすべて、共通のものがあります。直列化されたモデル(大きなファイル)を入力とし、テキストの解析などの具体的な処理を行うためのクラスを返すload/initメソッドがあります。重いリソースを読み込む共有クラスを実装するための洗練された方法(Javaの場合)

この状況を説明するためには、私はそれをラップするために以下のクラスを作成しているため、解析を行うためにConcreteParserのlibが、持って言うことができます:

public class ParserWrapper { 
    private static final ConcreteParser parser = null; 

    private static void init(String modelFileName) { 
     if (parser == null) 
      parser = ConcreteParser.load(modelFileName); 
    } 

    public static Result parse(input) { 
     if (parser == null) throw new RuntimeException(...); 
     return parser.parse(input); 
    } 

}

あなたは、これを見ることができるように最初にparseの前にinitを呼び出す必要があります。これは間違いなくnoです。私もシングルトンのパターンに基づいた解決策を試しましたが、私はまだ私がしたいことをする良い方法があると思います。

すべてのモデルは読み込みに比較的長い時間がかかり、多くのメモリを消費するため、ConcreteParserは静的です。したがって、私はそれらを使用するすべてのクラスにそれらを共有する必要があります。

私の質問は、私が欲しいことをする別の(よりエレガントな)方法はありますか?このコードを改善するにはどうすればよいですか?私はリソースをロードする単一のポイントを持つために、 "createParser"や "createTagger"のようないくつかのメソッドを持つResourceManagerクラスを作成することを考えました。このクラスは、各リソースがすでにインスタンス化されているかどうかをチェックします。これらのことはどうでもいいですか?

よろしくお願いいたします。

+0

ConcreteParserシングルトンがスレッドセーフであることが絶対に確実です! –

答えて

0

ResourceManagerを静的にしてから、ラッパーを初期化する前にすべての作成メソッドを呼び出すのはなぜですか?これは、シングルトンパターンを回避し、おそらく達成したいものとより密接に一致します。

3

私は、パーサーとテーガーなどを作成するためのクラスのようなクラスを作成し、特定のファイル名に対してこのクラスのキャッシュ結果を持たせることで、getParser(filename)の最初の呼び出しでパーサーが作成され、キャッシュされたパーサ これはシングルトンに似ていますが、ファクトリの共通インターフェイスを使用している場合は、パーサー全体を作成する代わりにモックを返すファクトリを作成できます。

このようにして、プログラムのどこかですべてのパーサーとタグ付け用のファクトリを作成し、プログラム内からこのオブジェクトを取得するのに適した方法を確保するだけです。

+0

ファクトリーに+1すると、後で詳細を簡単に変更することができます –

0

ファイルは変更されていますか?

:そうでない場合:静的な初期化ツール内でリソースとしてロードします。

もしそうなら: "上からのパラメータ設定"コンストラクタを通ってオブジェクトを一番下に通してください。

1

パーサーは不変であるようです。 (パーサーがnullでない場合、initは何もしません)なぜ静的にするのはどうですか?コンストラクターとパーサーをinitにしてParswerWrapperのメンバーにします。別のクラスを作成するか、醜いハックとしてSystem.setProperty()を使用します。これは、参照のみを保持するジョブであるシングルトンです。あなたが必要なファイルを事前に知っていれば、Enum!列挙型を使用し

#1

/*package*/ class ParserWrapper implements ParserWrapperInterface{ 
    private ConcreteParser p; 
    public ParserWrapper(String filename) { 
    p = ConcreteParser.load(p); 
    } 

    public Result parse(InputStream in) {...} 
} 

public Enum ParserManager { 
    instance; 

    private Map<String, ParserWrapper> map = new HashMap<...>() 

    public get(String filename) { 
    if(!map.containesKey(filename)) { 
     synchronized(ParserManager.class) { 
     if(!map.containesKey(filename)) { 
      map.put(filename, new ParserWrapper(filename)); 
     } 
     } 
    } 
    return map.get(filename); 
    } 
} 

#2

public Enum Parsers { 
ModelFoo("foo.mdl"), ModelBar("bar.mdl"); 

private ConcreteParser p; 

public Parser(String fname) { 
p = ConcreteParser.load(fname); 
} 

public Result parse(InputStream in) {...} 
} 

各列挙値のインスタンスが1つだけ今まで存在することを保証します。期間。 JVMは、クローン化、デシリアライズ、クラスローダー間の分割などができないことを保証するように設計されています。列挙型は単一のインスタンスを意味します。

関連する問題