Рефакторинг: когда нельзя использовать шаблон посетителя вместо switch/instanceof

Я пытаюсь выполнить рефакторинг фрагмента кода, используя instanceof, чтобы определить тип. Я думаю, что подтип/полиморфизм в этом случае не сработает (и даже если это будет слишком много в этой ситуации), и шаблон посетителя здесь не сработает, поскольку у меня нет возможности добавить метод accept в аннотация. Есть ли другие способы сделать такой код более чистым/читабельным?

for (Annotation annotation : method.getAnnotations()) {
            if (annotation instanceof DELETE) {
                setHttpMethod(annotation.annotationType().getSimpleName(), false);
                parsePath(((DELETE) annotation).value());
            } else if (annotation instanceof GET) {
                setHttpMethod(annotation.annotationType().getSimpleName(), false);
                parsePath(((GET) annotation).value());....

DELETE и GET выглядят так

public @interface DELETE {
  String value() default "";
}

public @interface GET {
  String value() default "";
}

Пример использования:

class Example {
      @DELETE("value") 
      Response method() {
...
      }
}

person user1769255    schedule 28.01.2016    source источник
comment
Вы можете использовать отражение для вызова accept   -  person Andrew Williamson    schedule 29.01.2016
comment
Не могли бы вы показать более подробную информацию? В настоящее время мне немного сложно что-либо предложить, не зная подробно вашего сценария. Что такое DELETE, что такое GET, есть ли аннотации, которые не следует учитывать, и т. д.?   -  person Marvin    schedule 29.01.2016
comment
Я не очень хорошо понимаю аннотации, но если annotation instanceof DELETE верно, то ((DELETE) annotation) является избыточным преобразованием. В этом случае внутри блока if будет просто setHttpMethod(annotation.annotationType().getSimpleName(), false); parsePath(annotation.value()); в обоих случаях. Тело когда-нибудь меняется?   -  person Miserable Variable    schedule 29.01.2016
comment
@MiserableVariable нет, это унизительно. В Annotation нет метода value(). Строка является экземпляром объекта. Если у вас есть переменная o типа Object и вы проверили, что o instanceof String, вы не можете сделать o.substring(). Вам нужно сделать ((String) o).substring().   -  person JB Nizet    schedule 29.01.2016
comment
Ой :) Я скоро удалю свой комментарий   -  person Miserable Variable    schedule 29.01.2016
comment
@JBNizet, тем не менее, не может ли OP объявить базовый тип аннотации с методом экземпляра value(), который возвращает правильное значение для любого типа аннотации во время выполнения? Все еще не шаблон посетителя, но код упрощается до if (annotation instanceof HttpVerb) { ...parsePath(((HttpVerb)annotation).value()); }   -  person Miserable Variable    schedule 29.01.2016
comment
@MiserableVariable Если бы java поддерживал наследование аннотаций, это могло бы сделать это, но это недоступно в java   -  person user1769255    schedule 29.01.2016
comment
Я не должен говорить о вещах, которые я плохо знаю. С другой стороны, я кое-чему научился. Я думаю, что меня смутил комментарий Луи Вассермана к ответу Дж. Б. Низе о том, что существует много аннотаций, которые являются подтипами DELETE, которые могут не быть аннотациями.   -  person Miserable Variable    schedule 29.01.2016


Ответы (1)


person    schedule
comment
Хм. Мне кажется, что есть много аннотаций, которые являются подтипами DELETE, что не обязательно является аннотацией. Я не уверен, что это сработает. - person Louis Wasserman; 29.01.2016
comment
Правда, может быть и так. Хотя я в этом сомневаюсь: эти аннотации выглядят как стандартные аннотации JAX-RS, а OP использует имя аннотации (DELETE, GET) в качестве метода HTTP. Так что я сомневаюсь, что на самом деле существует класс SomeDeleteAnnotation, реализующий DELETE, потому что нет HTTP-метода с именем SomeDeleteAnnotation. @ user1769255: поясните, пожалуйста. - person JB Nizet; 29.01.2016
comment
Существует ряд аннотаций (по одной на метод http), но ни одна из них не является подтипом другого типа. - person user1769255; 29.01.2016