如何用 guice 代替反射?

发布于 2024-12-11 08:51:05 字数 455 浏览 0 评论 0原文

我长期以来一直使用反射来将模块与“处理程序”解耦。

我有一个这样构建的代码库:

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 用域特定的逻辑处理程序“水合”我的控制模块?

I have long used reflection to decouple modules from "handlers".

I have a code base which is architected like this :

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

  private final Class c; 

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

  public Class getAnimalHandler()
  {
    return c;
  }
}

Then later in my code, I have a method which takes an "Animal" enum as input and uses reflection (that is, it gets the class from the enum and invokes "newInstance") to invoke the necessary handler.

I think the solution would be cleaner with Guice. How can I get rid of the enum/reflection and simply use guice to "hydrate" my control module with domain specific logic handlers?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

可爱暴击 2024-12-18 08:51:05

您可以很好地使用 MapBinder,并为每个可能的 AnimalEnum 值定义一个绑定。

You could well use a MapBinder<AnimalEnum, AnimalHandler>, and define a binding for each possible AnimalEnum value.

离笑几人歌 2024-12-18 08:51:05

我想这里一定有更好的模式。我对 Animal 枚举如何与处理程序交互有点困惑,但我会提出一些一般性建议,也许其中一个会坚持下去。

  • 我假设无法在 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 相比如何,但如果这是 Spring,我将实例化处理程序 bean,它们将向 AnimalHandlerMapper 注册以完全解耦它。

希望这有帮助。

I think that there must be a better pattern here. I'm a little confused as to just how the Animal enum interfaces with the handler but I'll make some general suggestions and maybe one will stick.

  • I assume that there is no way to define the handlers in the Animal enum and you want to decouple the classes. Fine.
  • Could the the handlers register themselves with Animal.setHandler(...)? Then you could just call Animal.Dog.getHandler() to get Dog's handler.
  • I agree with @jfpoilpret that some sort of AnimalHandlerMapper would also be better. I assume there a common interface is possible, even if it just a marker interface.

Code:

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);
}
  • If for some reason you can't use the handler instances then I would do the same thing but with handler factories. So you've call handlerMap.get(animal).create(animal) or some such. This would be much cleaner than using reflection.
  • I'm not sure how Guice compares to Spring but if this was spring I would instantiate the handler beans and they would register with the AnimalHandlerMapper to completely decouple it.

Hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文