2011-10-23 9 views
3

私は長い間、ハンドラからモジュールを切り離すためにリフレクションを使用してきました。反射をguiceで置き換えるにはどうしたらいいですか?

私はこのように設計されたコードベースがあります後、私のコードに続い

static enum AnimalHandlers { 
    Dog(Dog.class), 
    Cat(Cat.class); 

    private final Class c; 

    AnimalHandlers(Class class) 
    { 
    this.c=class; 
    } 

    public Class getAnimalHandler() 
    { 
    return c; 
    } 
} 

を、私はそれを取得し、入力として「動物」列挙型を取り、リフレクションを使用する方法(つまりを有しますenumのクラスを呼び出して "newInstance"を呼び出して)、必要なハンドラを呼び出します。

私は解決策がGuiceとのよりクリーンであると思う。どのようにしてenum/reflectionを取り除き、guiceを使用してコントロールモジュールをドメイン固有のロジックハン​​ドラで "水和"することができますか?

+1

あなたの例は実際のコードよりも単純すぎるかもしれませんが、これは単に 'new'を使うだけではなく、なぜ構造化されているのでしょうか?なぜ反射を使うのですか? – aparker42

+0

なぜなら、動物はさまざまな種類の動物であり、それらの大きなリストが異なるハンドラに制御を移すクラスに送られると想像してください。処理される動物の種類に依存するif文が必要です(ブロックにはいくつかの新しい文が含まれている必要があります)ので、動物を介してループを繰り返すロジックを動物自身に結びつけ、維持できないシステムにつながります。複数の開発者が簡単に拡張することはできません....そして、テストするのが難しいです。 – jayunit100

+0

正直言って、あなたのenumベースの解決策はそれほど悪くないと思います。ハンドラクラスをステートレスにすることができれば、すべての列挙定数に対して1つのインスタンスしか持たなくてもかまいません。 –

答えて

2

MapBinder<AnimalEnum, AnimalHandler>をよく使用し、可能な各AnimalEnum値のバインディングを定義できます。

+0

うーん...私は、これは完全に質問に答えていないことに気づいた:私は、列挙型を交換したいので - 私はちょうどクラスのリストを必要とする、と私はGuiceのが私のために醜い反射仕事をしたい - 私はそれを必要といけません。それは可能です/> – jayunit100

+0

まあ、私はあなたが望むものを完全に理解しているのか分からない。 MultiBinder を使用することもできますが、使用するハンドラはどのようにして知ることができますか?あなたは確かに具体的なユースケースであなたの質問を明確にする必要があります、またはより良い、新しい質問をしてください。 – jfpoilpret

2

ここではより良いパターンが必要だと思います。私はちょうどちょうどAnimal enumがハンドラとどのようにインタフェースするのか少し混乱していますが、私はいくつかの一般的な提案をしてくれます。

  • Animal列挙型にハンドラを定義する方法がなく、クラスをデカップリングするとします。ファイン。
  • ハンドラーはAnimal.setHandler(...)で登録できますか?その後、Animal.Dog.getHandler()に電話して、Dogのハンドラを取得できます。
  • 私は@jfpoilpretに同意して、ある種のAnimalHandlerMapperも良いでしょう。私はそこに共通のインタフェースが可能であると仮定します。

コード:

private static Map<Animal, AnimalHandler> handlerMap 
    = new HashMap<Animal, AnimalHandler>(); 
static { 
    Dog dog = new Dog(); 
    handlerMap.put(Animal.Dog, dog); 
    // we use the same handler twice here 
    handlerMap.put(Animal.Wolf, dog); 
    handlerMap.put(Animal.Cat, new Cat()); 
    // do a Animal.values loop at the end to verify that everyone has a handler 
} 

public static AnimalHandler getHandler(Animal animal) { 
    return handlerMap.get(animal); 
} 
  • もしあなたが、私は同じことを行うが、ハンドラの工場となり、ハンドラのインスタンスを使用することはできませんいくつかの理由があります。だから、handlerMap.get(animal).create(animal)またはそのようなものを呼び出しました。これは、反射を使用するよりもはるかにクリーンです。
  • GuiceがSpringとどのように似ているのか分かりませんが、春だった場合はハンドラBeansをインスタンス化し、AnimalHandlerMapperを登録して完全にデカップリングします。

これが役に立ちます。

関連する問題