Как я могу заменить отражение на хитрость? - PullRequest
3 голосов
/ 24 октября 2011

Я давно использовал отражение, чтобы отделить модули от "обработчиков".

У меня есть кодовая база, которая выглядит следующим образом:

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. Как я могу избавиться от перечисления / отражения и просто использовать подсказку, чтобы «увлажнить» мой модуль управления с помощью специфичных для домена логических обработчиков?

Ответы [ 2 ]

2 голосов
/ 25 октября 2011

Я думаю, что здесь должна быть лучшая модель.Я немного сбит с толку относительно того, как enum Animal взаимодействует с обработчиком, но я сделаю несколько общих советов, и, возможно, кто-то будет придерживаться.

  • Я предполагаю, что нет никакого способаопределите обработчики в перечислении Animal, и вы хотите разделить классы.Отлично.
  • Могут ли обработчики зарегистрировать себя с Animal.setHandler(...)?Тогда вы можете просто позвонить Animal.Dog.getHandler(), чтобы получить обработчик Пса.
  • Я согласен с @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, но если бы это была весна, я бы создал экземпляр бобов-обработчиков, и они регистрировались бы в AnimalHandlerMapper, чтобы полностью отделить его.

Надеюсь, это поможет.

2 голосов
/ 24 октября 2011

Вы вполне можете использовать MapBinder<AnimalEnum, AnimalHandler> и определить привязку для каждого возможного значения AnimalEnum.

...