ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 6장 - 예측 가능한 코드를 작성하라
    클린 코드(Clean Code)/좋은 코드, 나쁜 코드 요약 2023. 12. 15. 00:01
    728x90

    예측가능한 코드를 작성하는 방법

    • 매직값을 반환하지 않기
    • 널 객체 패턴을 적절하게 활용하기
    • 예상하지 못한 side-effect 피하기
    • 불변 객체 활용 또는 방어적 복사 활용하기
    • 열거형을 처리할 때는 미래를 고려하자
    • 그냥 테스트를 잘 작성하면 되지 않을까??

     

    매직값을 반환하지 않기

    오류가 발생했을 때 -1을 반환한다면 정상적인 반환값으로 오인하기 쉽습니다.

    js에서 배열에 대해 indexOf()를 호출할 때 이런 경우가 종종 있습니다.

     

    사용자의 평균 연령을 계산하려고 하는데 나이를 반환할 때 존재하지 않으면 -1을 반환하는 경우 함수의 작성자가 이를 예측하지 못하면 평균값 계산이 -1이 포함되기 때문에 잘못된 연산이 발생할 수 있습니다.

     

    대안책으로는 null, Optional<T>, 오류를 반환하면 됩니다.

    언어가 kotlin처럼 null-safe를 지원한다면 null을 반환하고 java처럼 그렇지 않다면 Optional을 반환해 줄 수 있습니다.

    이를 통해 호출하는 쪽에서 값이 없을 수 있음을 인지하고 적절한 방법으로 처리할 수 있습니다.

     

    널 객체 패턴을 적절하게 활용하기

    널 객체 패턴은 null을 반환하는 것이 아니라 유효한 값이 반환되어 그 이후에 실행되는 로직에서 null 값으로 인한 NullPointerException 등이 발생하지 않도록 하기 위함입니다.

     

    List를 활용하는 경우에는 null 대신에 빈 리스트를 넘겨주는 방식으로도 활용할 수 있습니다.

    //classNames가 emptyList일때 코드
    return classNames.contains("highlighted")
    
    //classNames가 null일때 코드
    if(classNames == null){
    	return false
    }
    
    return classNames.contains("highlighted")

     

     

    그러면 null 대신에 빈 문자열을 넘겨주는 방식은 어떠한가?

    null 대신 빈 리스트를 넘겨주기도 하니까 합리적으로 보이지만 때로는 문제를 발생시킬 수 있습니다.

    예를 들어 문자열이 ID로 사용되는 상황에서는 문장열이 없는지를 파악하는 것이 중요할 수 있습니다.

    이때는 null을 반환하는 것이 훨씬 낫습니다.

     

    새로운 휴대폰을 구매하고 박스를 받았는데 집에 와서 뜯어보니 빈 박스라면 어떨까요?

    호출하는 쪽에서 빈 상자를 받고 놀라거나 황당해할 가능성이 있다면 오히려 예외를 발생시키거나 null을 반환하는 것이 더 나은 선택일 수 있습니다. (널 객체 패턴을 사용하지 않는 방법)

     

    예상하지 못한 side-effect 피하기

    side-effect로는 DB 저장, 사용자에게 출력 표시, 캐시 업데이트 혹은 무효화, 다른 시스템 호출 등이 있습니다.

    호출하는 쪽에서 부수 효과가 예상되지 않을 경우 놀라움을 유발하고 버그로 이어질 수 있습니다.

     

    예시 사례로는 getXXX 함수를 호출하지만 갑자기 update가 발생한다면 예측하기 힘들 수 있습니다.

    함수의 이름을 분명하게 변경하여 예측가능하도록 변경할 수 있습니다. (updateAndGetXXX)

     

    불변 객체 활용 또는 방어적 복사 활용하기

    입력 매개변수를 수정하는 경우에는 예상치 못한 결과와 버그로 이어질 수 있습니다.

    변경할 필요가 있다면 변경하기 전에 새 자료구조에 복사하는 방법을 활용할 수 있습니다.

    불변 객체까지 같이 활용한다면 이런 행위를 강제할 수 있습니다.

     

    열거형을 처리할때는 미래를 고려하자

    예를 들어 A라는 열거형을 활용하고 if 열거형을 활용하는 경우라면 true를 반환하고 그렇지 않으면 false를 반환한다고 가정해 보겠습니다.

    새로운 B라는 열거형이 들어왔고 true를 반환해야 하지만 개발자 이를 챙기지 못하면 자연스럽게 false가 반환됩니다.

     

    모든 경우를 처리하는 스위치 문 혹은 kotlin으로 치면 when을 활용하여 처리하면 새로운 열거형이 추가되어도 컴파일에러가 발생하고 개발자가 챙길 수 있게 됩니다.

     

    그냥 테스트를 잘 작성하면 되지 않을까??

    어떤 개발자들은 테스트에 대해 그다지 부지런하지 않을 수 있습니다.

    또한 mock을 통해 테스트해야 할 수 있어서 테스트가 실제 상황을 정확히 재현하지 않습니다.

    멀티 스레드 코드 등 테스트하기 어려운 상황일 수 있습니다.

     

    테스트는 매우 중요하지만 코드 품질도 잘 고려하는 것도 중요합니다.

    댓글

Designed by Tistory.