Я не могу пересылать исключения из моего прокси-класса - PullRequest
1 голос
/ 29 марта 2019

У меня есть интерфейс:

public interface ThirdPartySystemCaller {
    void sendRequest(String request) throws ThirdPartySystemException;
}

И реализация:

@Slf4j
@Service
public class ThirdPartySystemCallerImpl implements ThirdPartySystemCaller {

    @Override
    public void sendRequest(String request) throws ThirdPartySystemException {

        if (request == null) throw new ThirdPartySystemException();

        log.info("send: {}", request);
    }
}

И у меня есть ведьма CryptoService, которая может подписать запрос:

public interface CryptoService {
    String signRequest(String request) throws CryptoException;
}

И Это реализация:

@Slf4j
@Service
public class CryptoServiceImpl implements CryptoService {

    @Override
    public String signRequest(String request) throws CryptoException {
        if (request.length() > 100) throw new CryptoException(); //just for example
        return "signed " + request;
    }
}

Теперь я могу пользоваться этими услугами:

String signedRequest = cryptoService.signRequest("Hello"); 
thirdPartySystemCaller.sendRequest(signedRequest); 

Но мне нужно каждый раз звонить в обе службы. Я хочу создать Proxy:

@Slf4j
@Service
public class ThirdPartySystemCallerSignedProxy implements ThirdPartySystemCaller {

    private final ThirdPartySystemCaller thirdPartySystemCaller;
    private final CryptoService cryptoService;

    public ThirdPartySystemCallerSignedProxy(ThirdPartySystemCaller thirdPartySystemCaller, CryptoService cryptoService) {
        this.thirdPartySystemCaller = thirdPartySystemCaller;
        this.cryptoService = cryptoService;
    }

    @Override
    public void sendRequest(String request) throws ThirdPartySystemException {
        String signedRequest = cryptoService.signRequest(request);
        thirdPartySystemCaller.sendRequest(signedRequest);
    }
}

Но мой ThirdPartySystemCallerSignedProxy реализует ThirdPartySystemCaller интерфейс и sendRequest метод сгенерирует только ThirdPartySystemException. Но если cryptoService бросить CryptoException, мне тоже нужно бросить.

Как я могу это сделать?

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

1 Ответ

0 голосов
/ 29 марта 2019

Создать базовое исключение

Вы можете создать абстрактное исключение BusinessException, которое может быть базовым исключением для ThirdPartySystemException и CryptoException.Теперь вы можете определить, что метод sendRequest выдает BusinessException, а реальное исключение зависит от данной проблемы.

Фасад

ThirdPartySystemCallerSignedProxy - это плохое имя, потому что оно напоминает Proxy шаблон, который вы не реализовали.Этот класс напоминает шаблон Facade , потому что вы хотите создать унифицированный интерфейс с более простым API для двух разных интерфейсов.В этом случае вы можете обернуть CryptoException, если он будет брошен в ThirdPartySystemException, или создать базовое исключение и объявить его в методе.Это даже лучше, потому что вы не знаете, какой тип исключения будет выдан, но наверняка это будет BusinessException.

Цепочка ответственности

Многие библиотеки используют Chain of Responsibility для обработки request -> response связи.Все ячейки цепочки должны реализовывать один и тот же интерфейс с базовым исключением в объявлении, если это необходимо.Вы можете построить цепочку в определении бина.Его немного проще поддерживать, потому что все ячейки независимы и не должны знать друг о друге, как в Facade.Вы можете построить цепочку в @Bean объявлении метода, как показано ниже:

@Bean
public ServiceChainCell thirdPartyCaller() {
    CryptoService crypto = cryptoService();
    ThirdPartySystemCaller caller = thirdPartySystemCaller();

    // Create chain
    crypto.setNext(caller);

    return crypto;
}

setNext метод происходит из интерфейса ServiceChainCell, который также должен иметь метод sendRequest(String request).

Подробнее оэти шаблоны, и вы найдете лучшее решение для вас.

...