Вы можете также рассмотреть возможность использования шаблона посетителя (https://en.wikipedia.org/wiki/Visitor_pattern),, так как он обеспечивает безопасность типов и не требует проверки экземпляра. Кроме того, более очевидно, когда вам нужно расширять / модифицировать свой код, когда вы создать новый тип запроса (например, «VerySpecialRequest»).
Все, что вам нужно сделать, - это создать интерфейс с методами посещения для каждого типа, для которого вы хотите выполнить специальный код, например:
public interface RequestProcessor {
void visit(Request request);
void visit(SpecialRequest specialRequest);
}
Классы запросов нуждаются в методах accept, которые ничего не делают, кроме как сами вызывают посетителя:
public class Request {
...
void accept(RequestProcessor requestProcessor) {
requestProcessor.visit(this);
}
}
То же самое для SpecialRequest:
public class SpecialRequest extends Request {
...
@Override
void accept(RequestProcessor requestProcessor) {
requestProcessor.visit(this);
}
}
Тогда вы можете просто реализовать свою логику в классе, который реализует интерфейс (здесь как анонимный класс):
RequestProcessor requestProcessor = new RequestProcessor() {
@Override
public void visit(Request request) {
System.out.println("I'm a normal request");
}
@Override
public void visit(SpecialRequest specialRequest) {
System.out.println("I'm a special request");
}
};
Request request = new Request();
request.accept(requestProcessor);
SpecialRequest specialRequest = new SpecialRequest();
specialRequest.accept(requestProcessor);
Как видите, экземпляров проверок больше нет. Еще одним преимуществом этого является то, что вы можете «обрабатывать запросы», даже если они не являются прямым подклассом «Request» - все, что вам нужно сделать, это извлечь метод accept в его собственном интерфейсе. Надеюсь, это поможет.