我无法转发代理类中的异常

时间:2019-03-29 13:30:19

标签: java oop exception design-patterns proxy-pattern

我有一个界面:

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 :(得分:0)

创建基本异常

您可以创建抽象异常BusinessException,它可以是ThirdPartySystemExceptionCryptoException的基本异常。现在,您可以定义sendRequest方法抛出BusinessException,而真正的异常取决于给定的问题。

门面

ThirdPartySystemCallerSignedProxy是一个不好的名字,因为它会提醒您未实现的Proxy模式。该类提醒Facade模式,因为您想为两个不同的接口创建具有更简单API的统一接口。在这种情况下,可以将CryptoException包装到ThirdPartySystemException中,也可以创建基本异常并在方法中声明。更好,因为您不知道会抛出哪种异常,但可以肯定会抛出BusinessException

责任链

许多库使用Chain of Responsibility处理request -> response的通信。如果需要,所有链单元都需要在声明中使用基本异常来实现相同的接口。您可以在bean定义中构建链。由于所有单元格都是独立的,并且不必像Facade那样相互了解,因此维护起来稍微容易一些。您可以在@Bean方法声明中构建链,如下所示:

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

    // Create chain
    crypto.setNext(caller);

    return crypto;
}

setNext方法来自ServiceChainCell接口,该接口也应具有sendRequest(String request)方法。

详细了解这些模式,您将找到最适合您的解决方案。