ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 계산기 미션 공통 피드백
    et cetera/TIL 2021. 4. 10. 20:09
    반응형

    주석

    주석도 코드의 일부라고 생각해야한다.

    주석을 작성할 때도 항상 명확한 이유를 가지고 작성을 하는 습관이 필요하다.

     

    1. 설명하는 주석

    명확하지 않은 코드를 주절주절 설명하는 주석을 의미하는 게 아니다.

    코드 자체만 보고도 무슨 코드인지 명확히 알 수 있는 코드를 작성하는 것이 당연히 가장 바람직하다.

     

    여기서 말하는 '설명'이란, 읽는 사람이 해당 코드에 대해 더 높은 이해를 할 수 있게 해주는 설명을 의미한다.

    코드에 담을 수 없지만, 코드를 이해하는 데에 도움이 되는 정보들.

    예를 들어

    // 이 데이터에서 이진트리는 해시테이블보다 40%정도 빠르다.
    // 재귀함수를 이용하면, 기존의 100line이 될수 있는 코드가 단 20줄로 정리된다. 반면 성능은 유의미한 차이가 없다.
    

     

    이런 주석이 달려있다면, 이 코드를 읽는 사람은 코드의 성능을 최적화하려는 불필요한 시도를 하지 않아도 된다.

     

    2. 코드의 결함을 알려주는 주석

    현재 코드가 가지는 결함을 공개적으로 드러내고, 수정할 여지를 남겨주는 것을 의미한다.

    // TODO: JPEG외 다른 이미지 포맷도 처리할 수 있어야 한다
    

     

    이런 TODO 주석들은 팀원들과 협업할 때 뿐만 아니라, 본인 스스로에게도

    현재 코드에 남아있는, 해결해야하는 결함들에는 어떤 것들이 있는지를 상기시켜준다.

     

    예시로 딱 적합한 React 코드의 주석.

    // AsyncMode should be deprecated
    export function isAsyncMode(object: any) {
      if (__DEV__) {
        if (!hasWarnedAboutDeprecatedIsAsyncMode) {
          hasWarnedAboutDeprecatedIsAsyncMode = true;
          // Using console['warn'] to evade Babel and ESLint
          console['warn'](
            'The ReactIs.isAsyncMode() alias has been deprecated, ' +
              'and will be removed in React 18+.',
          );
        }
      }
      return false;
    }
    

     

    3. 상수에 대한 설명

    상수 네이밍만으로는 온전히 설명하기 힘든, 해당 상수가 만들어진 배경이나 의도같은 것들을 설명하는 경우.

    // 합리적인 한계 - 1000개 이상을 구독하는 사람은 기획 논의상 없다.
    const MAX_SUBSCRIPTIONS = 1000
    
    // 사용자들은 0.72가 크기/해당도 대비 최선이라고 생각한다.
    const IMAGE_QUALITY = 0.72
    

     

    4. 사용자들이 빠질 수 있는 함정을 미리 경고

    // 이 함수는 외부 서비스를 호출하여, 이메일을 발송한다 (1분정도 소요)
    function sendEmail() {
    ...
    }
    

     

    사용자에게 이메일을 보내는 서드파티 라이브러리의 함수 코드라고 치자.

    이 주석만 봐도 함께 개발하는 사람은 1분 정도 소요된다는 걸 알려주는

    애니메이션이나 알람을 만들어 줘야겠다는 생각을 할 수 있게 된다.

    혹은, 만약 위의 주석이 작성되어있지 않다면 이 함수를 사용하는 사람은 왜 메일을 보내는 데 1분이나 걸리는지,

    시간이 너무 오래 걸리는데 혹시 에러가 발생한 건 아닌지 일일이 테스트를 해봐야 한다.

     

    불필요한 임시 변수 없애기

    // X
    function generateRandomNumber(minNum = MIN_INPUT_NUMBER, maxNum = MAX_INPUT_NUMBER) {
      const randomNumber = Math.floor(Math.random() * (maxNumber + 1) + minNumber);
      
      return randomNumber;
    }
    
    // O
    function generateRandomNumber(minNum = MIN_INPUT_NUMBER, maxNum = MAX_INPUT_NUMBER) {
      return Math.floor(Math.random() * (maxNumber + 1) + minNumber);
    }

    이런 임시 변수들은 재사용성에서의 이점도 없고, 코드를 더 명확하게 하는 데에 딱히 도움이 되지도 않는다.

     

    전역 변수 최대한 적게 쓰기

    코드가 길어지면, 전역변수가 어디서 어떻게 사용되고 있는지를 일일이 확인하기도 어렵고

    지역변수와 전역변수의 이름이 중복되는 경우도 종종 있다.

    또한, 읽는 사람이 한 번에 생각해야하는 변수의 수와 범위를 줄여주는 게 코드를 더 쉽게 만들어준다.

     

    값을 한 번만 할당하는 변수 선호하기

    let 보다는 const를 많이 쓰자는 뜻.

    변수들의 값이 자꾸 변하는데, 그런 변수가 한두개가 아니라면 프로그램을 추적하기는 점점 어려워질 것이다.

    변수가 어떤 상황에서 어떤 값으로 변하는지를 일일이 기억해야하기 때문.

    즉, 변수 값이 달라지는 곳이 많을수록 변수의 현재값을 추측하기는 더 어려워진다는 뜻.

    그래서 최대한 const를 애용하고, let을 사용하더라도 최대한 값을 적게 변경하자.

     

    네이밍

    네이밍만으로도 코드의 흐름을 파악할 수 있을 정도로 명확한 이름을 지으려 노력할 것.

    arr1, arr2, arr3 같은 네이밍은 최악.

     

    파라미터 갯수

    매개변수가 많아지면 함수를 호출할 때 전달하는 인수의 순서를 고려해야한다.

    이는 함수를 사용하기 까다롭게 만들고, 실수를 발생시킬 가능성을 높인다.

    매개변수의 개수나 순서가 변경되면 코드 전체가 영향을 받기도 한다.

    즉, 함수의 매개변수는 코드의 이해를 방해하는 요소라고 볼 수 있으며

    가장 이상적인 매개변수의 갯수는 0개이다. 굳이 0개가 아니더라도 적을수록 좋다.

    이상적인 함수는 한 가지 일만 해야하고, 가능한 작게 만들어야 한다는 것과 궤를 같이한다.

    만약 매개변수의 수가 불필요하게 많아지면, 객체로 감싸서 전달받는 것이 좋다.

     

    원격 저장소에 push할 것

    원격 저장소에 프로젝트를 올릴 때는, 항상 push 하지 않을 파일들을 구분해서

    반드시 push를 해야하는 파일들만 원격 저장소에 올리도록 하자.

     

    예외 사항

    항상 예외 사항에 대해서 깊게 고민해볼 것.

     

    테스트 가능한 부분

    테스트 가능한 코드와 테스트 하기 힘든 부분은 분리되어야 한다.

    const FORWARD_NUM = 4
    
    const getRandomNumber = () => {
      return Math.floor(Math.random() * 10)
    }
    
    function Car() {
      this.poistion = 0
    
      this.move = () => {
        if (getRandomNumber() >= FORWARD_NUM) {
          this.position++
        }
      }
    }
    

    위의 코드에서, move에 사용되는 랜덤 숫자는 매 테스트마다 달라질 수밖에 없다.

    Math.random으로 숫자가 랜덤하게 생성된다는 건 이미 증명이 된 부분이기 때문에,

    해당 부분은 분리해내고 테스트 가능한 코드만으로 구성을 하면 다음과 같이 수정할 수 있다.

    function Car() {
      this.poistion = 0
    
      this.move = (number) => {
        if (number >= FORWARD_NUM) {
          this.position++
        }
      }
    }
    

     

    테스트를 하기 난감한 부분이 있다면, 요런 식으로 리팩토링을 해보는 걸 추천.

    반응형

    댓글

Designed by Tistory.