Архитектура API дженериков Java - PullRequest
0 голосов
/ 30 октября 2019

Я реализую шаблон стратегии для обработки исключений

 public class GlobalExceptionHandler {

    private interface Strategy<T extends Exception> {
        ErrorResponse extract(T e);
    }

    private static class ResponseStatusStrategy implements Strategy<ResponseStatusException> {
        @Override
        public ErrorResponse extract(ResponseStatusException e) {
            return ErrorResponse.builder()
                    .status(e.getStatus())
                    .message(e.getReason())
                    .description(e.getReason())
                    .build();
        }
    }

    private static class IllegalStateStrategy implements Strategy<IllegalStateException> {
        @Override
        public ErrorResponse extract(IllegalStateException e) {
            return ErrorResponse.builder()
                    .status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .message(e.getMessage())
                    .description("")
                    .build();
        }
    }
    ....

Я называю этот API следующим образом:

Exception ex = ....; // function param
if (ex instanceof ResponseStatusException) {
    errorResponse = new ResponseStatusStrategy().extract((ResponseStatusException) ex);
} else if (ex instanceof IllegalStateException) {
    errorResponse = new IllegalStateStrategy().extract((IllegalStateException) ex);
} else {
    errorResponse = new EmptyStrategy().extract(ex);
}

Есть ли более эффективный и красивый способ реализовать это? Идея подсказывает мне, что я даже не использовал интерфейсный метод: «метод extract (T e) никогда не используется».

Было бы здорово иметь такой API:

    Strategy<???> strategy;
    if (ex instanceof ResponseStatusException) {
        strategy = new ResponseStatusStrategy();
    } else if (ex instanceof IllegalStateException) {
        strategy = new IllegalStateStrategy();
    } else {
        strategy = new EmptyStrategy();
    }
    errorResponse = strategy.extract(ex);

1 Ответ

2 голосов
/ 30 октября 2019

Вы пытаетесь решить проблему создания объекта. Вы хотите конкретный объект класса Strategy, основанный на классе StatusException. Создайте новый класс с фабричным шаблоном, который вернет вам правильный объект. Вот некоторый фиктивный код, вдохновленный вашим кодом.

private interface Factory {
    Strategy buildStrategy(Exception e);
}
private static class FactoryImpl implements Factory {
    public Strategy buildStrategy(Exception e) {
        if (e instanceof IOException) {
            return new Strategy1();
        } else {
            return new EmptyStrategy();
        }
    }
}

private interface Strategy<T extends Exception> {
    String extract();
}
private static class Strategy1 implements Strategy<IOException> {
    @Override public String extract() {
        return "Strategy1";
    }
}
private static class EmptyStrategy implements Strategy<NamingException> {
    @Override public String extract() {
        return "EmptyStrategy";
    }
}

public static void main(String[] args) {
    var f = new FactoryImpl();
    System.out.println(f.buildStrategy(new IOException()).extract());
    System.out.println(f.buildStrategy(new NamingException()).extract());
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...