티스토리 뷰

반응형

 

1. 오류 코드보다 예외를 사용하라

얼마 전까지만 해도 예외를 지원하지 않는 프로그래밍 언어가 많았어요. 오류 플래그를 설정하거나 호출자에게 오류 코드를 반환하는 방법이 전부였어요. 하지만 이렇게 코드를 작성하면 호출자 코드가 복잡해지고 코드 블록 depth가 깊어져요.

그래서 try / catch 등의 예외 처리를 하는 것이 더 깔끔해요. 오류 발생시 처리하는 코드와 예외 처리가 분리되기 때문이에요.

 

나의 생각: 사실 Swift는 Optional의 존재로 오류 처리가 한결 더 수월한 것 같아요. 현업 코드에서 오히려 try / catch를 거의 못 봤던 것 같아요. 오류가 발생하기 가장 쉬운 부분 중 하나가 네트워킹일 텐데 그 부분마저도 Optional 처리가 되기 때문에 오류 처리 대응이 쉽게 되었던 것 같아요. 책에서 나오는 예시도 오류 발생이 파일 이름을 읽을 때, 잘못된 파일 이름이거나 하는 부분인데 이 부분마저도 Optional 처리를 했었어요. 또한 에러는 Error 타입을 생성해서 Switch문으로 관리했기 때문에 더 편했던 것 같아요. 그래도 try / catch 오류 처리는 반드시 숙지해둬야 할 부분이므로 아래 규칙들을 잘 지켜보려고 해요.

 

2. Try-Catch-Finally 문부터 작성하라

어떤 면에서 try 블록은 트랜잭션과 비슷해요. try 블록에서 무슨 일이 생기든지 catch 블록은 프로그램 상태를 일관성있게 유지해야 해요.

try / catch 구조로 범위를 정의하고 난 후 TDD를 사용해 필요한 나머지 논리를 추가해요.

먼저 강제로 예외를 일으키는 테스트 케이스를 작성한 후 테스트를 통과하게 코드를 작성하는 방법을 권장해요. 그렇게 되면 자연스럽게 try 블록의 트랜잭션 범위부터 구현하게 되므로 트랜잭션 본질을 유지하기 쉬워져요.

 

3. 미확인(unchecked) 예외를 사용하라

확인된 예외란?
- java.lang.exception 클래스의 객체 또는 해당 하위 클래스예요. 확인된 예외는 컴파일 타임에 확인돼요(e.g. IOException).

확인된 예외는 OCP(Open Closed Principle)을 위반해요. 메서드에서 확인된 예외를 던졌는데 catch 블록이 세 단계 위에 있다면 그 사이 메서드 모두가 선언부에 해당 예외를 정의해야 해요. 즉, 하위 단계에서 코드를 변경하면 상위 단계 메서드 선언부를 전부 고쳐야 해요.

 

4. 예외에 의미를 제공하라

예외를 던질 때는 전후 상황을 충분히 덧붙여요. 

 

5. 호출자를 고려해 예외 클래스를 정의하라

오류를 분류하는 방법은 다양해요. 오류가 발생한 위치로 분류, 오류가 발생한 컴포넌트로 분류, 혹은 유형으로도 분류가 가능해요.

 

나의 생각: 책의 예시는 Java이기 때문에 오류 처리 방식이 매우 다르지만, 오류 상황을 정의하는 부분에 있어서는 어떤 언어든 필요한 개념이라고 생각해요. 그동안 오류가 발생했을 때 어떤 처리를 할 것인지, 어떤 구조로 오류를 처리할 것인지에 대한 고민이 절대적으로 많았는데 오류를 정의하는 부분에 있어서는 상대적으로 가볍게 생각했던 것 같아요. 

 

6. null을 반환하지 마라

한 줄 건너 하나씩 null을 확인하는 코드로 가득한 애플리케이션이 많아요. null을 반환하는 코드는 일거리를 늘릴 뿐만 아니라 호출자에게 문제를 떠넘겨요. 누구라도 null 확인을 빼먹으면 애플리케이션이 통제 불능에 빠질지도 몰라요.

 

나의 생각: 저자의 의도는 일일이 신경 써 확인해야 하는 null을 남발하면 큰 프로젝트 코드를 작성 시 실수를 유발할 수 있다는 뜻으로 받아들였어요. 하지만 Swift나 (심지어 Java도) Optional을 통해 명백하게 null / nil의 사용을 표현할 수 있다고 생각해요. 예전 Java 코드에서는 null 처리가 어려웠기 때문에 문제가 될 수 있지만 현재 이 주제에 대해 저는 저자와 조금 다른 생각을 가지고 있어요. 오히려 null / nil을 적절히 사용함으로써 코드가 더 명백해질 수 있다고 생각해요. 다만, 굳이 null / nil 처리하지 않아도 될 부분까지 생각 없이 무조건 처리해서 if let / guard let 같은 처리 구문을 남발해 전체 흐름에 영향을 주는 건 당연히 안 좋다고 생각해요. 다만, 일거리를 크게 늘린다거나 호출자에게 문제를 떠넘기는 구조로만 치부할 필요는 없다고 생각해요.

 

7. null을 전달하지 마라

메서드에서 null을 반환하는 방식도 나쁘지만 메서드로 null을 전달하는 방식은 더 나빠요. 

 

8. 결론

깨끗한 코드는 읽기도 좋아야 하지만 안정성도 높아야 해요. 이 둘은 상충하는 목표가 아니에요.

 

 

 

클린코드(Clean Code) by Robert.C.Martin
반응형
댓글