중요한 처리로직 인 경우, 어차피 caller는 callee를 믿어서는 안된다.

  • 여기서 callee는 다른 class 혹은 다른 class의 메서드를 의미한다.
  • 같은 class 내 private method를 호출하는 경우라면, 자기 자신이 직접 정의한 기능이므로 믿을 수 있으나, class 바깥의 다른 class와 메시지를 주고 받는 상황이라면 신뢰하지 않는 것을 기본 전제로 깔고가야 한다.

 

예시 ) 금액 소진 메서드를 제공하는 callee가 Exception을 반환하지 않겠다고 docstring에 명시해두었다면 믿을 것인가?

  • 금액 소진 기능인데, callee의 docstring과 현재 구현된 메서드 내부만 믿고 caller는 catch 안할 것인가? 그럴리가 없다는 것이다. 
  • caller 입장에서 callee는 언제든 변경될 수 있는 대상으로 바라보는 것이 더 안전하다.
  • catch를 해야 하는 중요 구간이라면, callee가 throw하지 않겠다고 하더라도 caller는 catch를 어차피 넣을거다.

 

val result: Result<T, R> = callee {
    try {
        throwableCall()
    } catch { return Result(FAILURE, null) }
    return Result(SUCCESS, data)
}
if (result.code != SUCCESS) { ... }
val data: T = result.data
data ...

코드 예시 ) callee가 자기 자신을 try-catch로 감싸서 절대로 Exception이 발생하지 않도록 한 다음, Result<T, R>을 반환하는 방식인데

 

caller 코드에서 try-catch를 제거 할 수 있어 깔끔해 보일 수는 있겠으나, 아래와 같이 처리하기에는 불안한 감이 있다. 

caller는 callee가 절대로 Exception을 던지지 않을 것이라고 믿을 수 있겠는가?

 

 

그래서 if와 try-catch의 일원화는 불가능하다고 봐야 한다.

예상된 실패 및 데이터가 존재하는 실패는 if로 처리하지만,

예상치 못한 실패를 위한 백업 try-catch는 항상 존재해야 한다.