我一直使用反射来将模块与"处理程序"解耦。
我有一个代码库,架构如下:
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的解决方案会更简洁。我怎样才能摆脱枚举/反射,并简单地使用向导来"水合物"我的控制模块与领域特定的逻辑处理程序?
您可以使用MapBinder<AnimalEnum, AnimalHandler>
,并为每个可能的AnimalEnum
值定义绑定。
我认为这里一定有更好的模式。我有点困惑,只是如何Animal
enum接口与处理程序,但我会提出一些一般性的建议,也许一个会坚持。
- 我假设没有办法在
Animal
枚举中定义处理程序,并且您想要解耦类。好。 - 处理程序可以注册自己与
Animal.setHandler(...)
?然后你可以调用Animal.Dog.getHandler()
来获取Dog的handler。 我同意@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
以完全解耦。