오류 처리는 중요하다. 하지만 오류 처리코드로 인해 프로그램 논리를 이해하기 어려워진다면 깨끗한 코드라 부르기 어렵다.
깨끗하고 튼튼한 코드를 짜기 위해 우아하게 오류를 처리해보자.
오류 코드보다 예외를 사용하라
- 비즈니스 논리와 오류 처리 코드와 뒤섞이지 않고 분리 되므로 호출자 코드가 더 깔끔해진다.
Try-Catch-Finally 문부터 작성하라
- try-catch-finally 문으로 시작하면, try 블록에서 무슨 일이 생기든지 호출자가 기대하는 상태를 정의하기 쉬워진다.
- 먼저 강제로 예외를 일으키는 테스트 케이스를 작성한 후 테스트를 통과하게 코드를 작성하는 방법을 쓰면, 자연스럽게 try 블록의 트랜잭션 범위 부터 구현하게 되므로 범위 내에서 트랜잭션 본질을 유지하기 쉬워진다.
미확인 예외를 사용하라
- 확인된 예외(모든 예외 정의)는 모든 의존성을 수정해야할 리스크가 있다.
예외에 의미를 제공하라
- 기본 예외 호출 스택뿐만 아니라, 오류 메시지에 충분한 정보를 담아 예외와 함께 넘겨준다.
호출자를 고려해 예외 클래스를 정의하라
- 예를 들어 외부 라이브러리를 호출할 때, 외부 라이브러리가 던질 예외까지 직접 처리하지 말고 감싸기 기법을 통해 독자적인 예외 클래스를 하나로 두자.
public void open(){
try {
innerPort.open();
} catch (DeviceReponseException e) {
throw new PortDeviceFailure(e);
} catch (ATM1212UnlockedException e) {
throw new PortDeviceFailure(e);
} catch (GMXError e) {
throw new PortDeviceFailure(e);
}
}
정상 흐름을 정의하라
- 논리와 오류 처리를 잘 분리하다보면 오류 감지가 프로그램 언저리로 밀려나게 되어, 논리를 따라가기 어렵게 될 수 있다.
- 이럴때는 특수 사례 패턴(클래스를 만들거나 객체를 조작)을 통해 예외를 처리하자.
null을 반환하지 마라
- null은 일거리를 늘릴 뿐만 아니라 호출자에게 문제를 떠넘긴다. 나쁘다 쓰지 말자!
- 메소드에서 null을 반환하고 싶다면 그 대신 예외를 던지거나 특수 사례 객체를 반환하자.
null을 전달하지 마라
- 호출자가 실수로 넘기는 null을 적절히 처리하는 방법이 없다.
- null을 반환하는 것보다 메소드로 null을 전달하는게 더 나쁘다. 무조건 피하자.
결론
깨끗한 코드는 읽기도 좋아야 하지만 안정성도 높아야 한다.
오류 처리를 프로그램 논리와 분리해 독자적인 사안으로 고려하자!
Reference
클린 코드: 애자일 소프트웨어 장인 정신 - 로버트 마틴 지음