본문 바로가기

BOOK Review

[클린코드] TIL - 7장 오류 처리

💙 TIL (Today I Learned)

  • 오류 처리 : 프로그램의 실행을 위해 반드시 필요한 것. 깨끗한 코드와 연관이 있음
  • 오류 코드보다 예외 사용하기
    • if-else 문 내의 `logger.log("~~"); 방식 지양
      -> 프로그램은 멈추지 않으나 로그만 찍히게 됨. 함수를 호출한 즉시 오류를 확인하지 않으면 묻힐 것
      => 예외를 던지는 편이 논리 - 오류 처리 코드가 섞이지 않으며 오류를 빨리 찾을 수 있음
      `try-catch` 문을 사용한 `throw Error()` 방식이 좋음
    • try-catch-finally 문 부터 작성하기
      • try 내부의 내용은 하나의 트랜젝션이 됨. catch 는 어떤 에러가 나든 같은 방식으로 처리가 됨
      • try-catch-finally 부터 시작해야 호출자가 기대하는 함수 상태의 정의를 내리기 쉬움
    • unchecked exception 사용하기
      • checked exception 은 OCP 원칙을 위배함 (상위 메서드까지 Exception 처리가 필수임)
    • 예외에 의미 제공하기
      • 전후 상황을 덧붙여 발생 원인과 위치를 빠르게 찾을 수 있게 해야함
    • 호출자를 고려해 예외 클래스 정의하기
      • 유형 / 발생한 컴포넌트로 오류를 분리하는 것이 아닌 오류를 잡아내는 방법으로 오류가 분류되어야함
      • BAD) 외부 API와 연동시 외부 라이브러리가 던질 예외를 모두 잡아서 예외 처리
      • GOOD) 호출하는 라이브러리 API 를 감싸서 예외 유형 하나로 반환
public class LocalPort { // 외부 라이브러리를 감싸는 클래스

  private ACMEPort innerPort; // 외부 라이브러리

  public LocalPort(int portNumber) {
    innerPort = new ACMEPort(portNumber); // 인자 전달받아 외부 라이브러리 객체 생성
  }

  public void open() {
    try {
      innerPort.open(); // 외부 라이브러리 함수 호출
    } catch (DeviceResponseException e) { // 외부 라이브러리에서 발생되는 에러는 호출자 입장에서는 모두 같으므로
      throw new PortDeviceFailure(e);
    } catch (ATM1212UnlockedException e) {
      throw new PortDeviceFailure(e);
    } catch (GMError e) {
      throw new PortDeviceFailure(e);
    }
  }
}

 

  • null 을 반환하지 않기
    • 호출하는 쪽에서 null 처리를 하지 않으면 예상치 않은 NullPointerException 을 받고 프로그램이 종료될 수 있음
    • 어디서 호출되는지 일일히 체크할 수 없고, 함수 확장에 지장을 주므로 빈 리스트 등을 활용하는 편이 좋음
  • null 을 전달하지 않기
    • 함수의 인수로 null 을 전달하게 될 경우도 NPE가 발생할 수 있음
    • sol 1) 함수에서 인수에 대한 null 체크하기
    • sol 2) assert문 사용하기
      • `assert p1 != null : "p1 should not be null"; 
      • tip)
// 방법 1
assert expression1;
// 표현식1이 참일 경우 그냥 지나감. 거짓일 경우 AssertionError 발생

assert expression1: expression2;
// 표현식1이 거짓인 경우 두번째 표현식의 값이 예외 메세지로 보여지게 됨

 

  • 오류 처리를 프로그램 논리와 분리하면 독립적인 추론이 가능해지며 유지보수성도 높아짐

💛 오늘 읽은 범위

7장 오류처리

 

🩶 기록

null 처리를 제대로 하지 않아 자바로 개발을 하며 NPE오류를 정말 많이 마주했다. NPE의 가장 큰 문제는 오류가 어디서 나는지, 어떠한 상황에 null이 들어가게 되는지 정확히 판단할 수 없어 발생하는 것 같다. 이를 피하기 위해 이 책에서 sol 1)로 알려줬듯, 메서드 에서 인자가 null인지 체크를 하는 로직을 넣었지만 많은 함수에 거의 비슷한 null checking 로직을 넣는 것은 비즈니스 로직을 흐리게 만드는 일이다.

이미 만든 메서드들을 일일히 체킹하면서 null을 반환하는지 찾는 것은 쉬운 일이 아니라고 생각한다. 개발 초반부터 null에 대한 처리를 확실히 고려하는게 중요하다.