如何用guice替换反射?

时间:2011-10-23 20:13:46

标签: java reflection dependency-injection 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;
  }
}

然后在我的代码中,我有一个方法,它将“Animal”枚举作为输入并使用反射(也就是说,它从枚举中获取类并调用“newInstance”)来调用必要的处理程序。

我认为Guice的解决方案会更清晰。如何摆脱枚举/反射,只需使用guice用特定于域的逻辑处理程序“保湿”我的控制模块?

2 个答案:

答案 0 :(得分:2)

您可以使用MapBinder<AnimalEnum, AnimalHandler>,并为每个可能的AnimalEnum值定义绑定。

答案 1 :(得分: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比较,但如果这是春天,我会实例化处理程序bean,他们会注册AnimalHandlerMapper以完全解除它。

希望这有帮助。