본문 바로가기
better code

Clean Code (3/n)

by marble25 2022. 2. 11.

지난번에 이어서 계속해서 Clean Code 책을 읽고 정리해 보았다. 

 

7. 오류 처리

자바를 배우면서, 자바를 사용하면서 깔끔하지 않은 오류 처리들을 많이 보았다. 

특별한 이유 없이 무조건적으로 try catch 문을 사용해서 묶인 코드를 보면서 '깔끔하지 않은 코드'라는 생각을 많이 했었다.

하지만, 현대적인 프로그래밍 언어들에서 오류 처리는 필수 불가결한 존재이고, 오히려 오류 처리를 적절하게 한다면 더 깔끔한 코드를 작성할 수 있다. 

좀 더 깔끔한 코드로 오류 처리를 할 수 있을까?

확인된 예외가 정답은 아니다

확인된 예외라는 표현이 모호했지만, 검색을 통해 찾아보니 미리 정의된 예외(IOException, SQLException 등)을 말한다고 한다. 

사실 기정의된 예외를 사용한다면 의미가 명확하고, 어떤 경우에 throw되고 처리되는지를 쉽게 알 수 있어서 좋다고 생각했다. 

하지만 단점으로는 메소드에서 확인된 예외를 던지기로 정의했다면, 그 메소드를 호출하는 또다른 메소드에서는 반드시 해당 예외에 대한 처리를 해야 한다. 

해당 예외에 대한 처리는 상위 메소드까지 타고 올라가서 최종적으로 처리해주는 try catch까지 도달해야 한다. 

이 과정에서 leaf 메소드의 수정은 연쇄적인 수정을 낳을 수 있기 때문에 개발자의 공수가 많이 들 수 있다. 

따라서 예외 클래스를 사용한다면 충분한 고민 후 사용하는 것이 맞는 것 같다.

예외를 의미있게 만들어라

예외를 전달할 때 예외 상황에 대한 충분한 정보를 제공하라는 의미이다.

예외 상황에 대해 더 자세한 로그를 남길수록 버그를 수정해서 더 좋은 프로그램으로 갈 수 있는 확률이 높아진다. 

 

예외를 의미있게 처리해라

불필요한 예외(특히 다른 외부 라이브러리를 사용할 때)를 뱉는 메소드가 있을 수 있다. 

예외에 따라 특별히 다른 처리를 해주지 않는다면 예외끼리 묶어서 로그만 남겨주는 방식으로 처리하는 편이 나을 수 있다. 

 

null 리턴을 지양해라

사실 이 부분이 직접적으로 오류 처리와 관련이 있는지는 모르겠다.

아마 저자가 오류를 내지 않는 코드 방식을 제안한 것일 수도 있겠다.

읽으면서 크게 공감했던 부분으로, 다른 메소드에서 리턴한 null로 인해 NullPointerException이 발생한 경우를 많이 보았다.

배열을 리턴한다면 빈 배열을, Object를 리턴한다면 빈 오브젝트를 리턴해서 리턴값이 비었는지 체크하는 편이 더 낫지 않을까 라는 생각을 평소에도 많이 하고 그런 방식으로 처리하려고 노력하는 편이라 이 부분을 한번 더 되새겨 보았다.

 

8. 경계

처음 이 부분을 딱 봤을 때에는 경계가 무엇을 의미하는지 와닿지 않았다.

알고보니 외부 라이브러리나 다른 모듈과의 integration을 의미하는 말이었다.

사실 이 파트에서 얻을 수 있는 교훈은 많지 않았고, 굳이 뽑자면 '테스트 코드'를 통해 사용법을 익히고 이를 실코드로 변환해 보자는 것 정도를 꼽을 수 있겠다.

 

9. 단위 테스트

최근에 점점 중요성을 체감해가는 부분으로, 개발을 해 나가면서 내 코드를 보증하는 것은 잘 짜여진 테스트 코드뿐이라는 것을 알게 되었다.

백엔드는 테스트 코드를 작성하기도 용이하고, 정형화된 방법이 있는데 반해 최근에는 프론트엔드에서도 UI 테스트 코드가 절실히 필요함을 깨닫고 있다.

그런 측면에서 단위 테스트를 어떻게 작성해야 하는지 간략하게 소개하고 있다.

 

테스트 코드도 'Clean'해야 한다

사실 실제 코드가 변경되면 테스트 코드도 변경되어야 하는 경우가 허다하다. 

그런 상황에서 테스트 코드가 '냄새나는 코드'이면 어떨까?

오히려 실제 코드를 변경 완료한 후에 실제 코드와 테스트 코드의 싱크를 맞추려고 공수를 들이면서 배보다 배꼽이 더 큰 상황이 오게 된다.

테스트 코드 역시 유연하고, 유지보수 가능하고, 재사용 가능해야 한다.

 

테스트 당 개념 하나

혹자는 테스트 메소드 하나당 assert 하나를 강요하기도 한다.

하지만 저자는 그 조건은 너무 가혹하며, '테스트 하나당 개념 하나'를 제안하고, 나도 이런 제안에 동의한다.

하나의 테스트에서는 반드시 하나의 개념만을 테스트하면 해당 테스트가 어떤 것을 테스트하는지 알아보기도 쉽고, 테스트에 실패했을 때 버그를 수정하기도 쉬워진다.

 

F.I.R.S.T

 

깨끗한 테스트가 갖춰야 할 조건이다.

  • Fast: 테스트를 실행하는 시간이 너무 길면 안된다.
  • Independent: 각각의 테스트가 의존적이면 안된다. 하나가 실패했을 때 다른 것도 실패할 가능성이 커지므로 원인을 알아내기가 쉽지 않을 수 잇따.
  • Repeatable: 테스트는 어떤 환경에서도 반복 가능해야 한다.
  • Self-Validating: 테스트가 스스로 성공과 실패를 내뱉을 수 있어야 한다. 테스트는 항상 성공 혹은 실패다.
  • Timely: 테스트 코드는 적시에 작성해야 한다.

'better code' 카테고리의 다른 글

[TIL] copy-on-write 방법론 - js에서 퍼포먼스 테스트  (0) 2023.04.22
Clean Code (5/n)  (0) 2022.02.21
Clean Code (4/n)  (0) 2022.02.16
Clean Code (2/n)  (0) 2022.02.07
Clean Code (1/n)  (0) 2022.02.05