Back to Blog
Featured image for 생각 안하고 코드 읽기

생각 안하고 코드 읽기

December 22, 20253 min read

생각 안하고 코드를 읽기 위해서는 코드가 읽기 좋아야 한다.

그럼 자연스레 "가독성 좋은 코드는 무엇인가?" 로 이어진다.
나는 이게 UX와 유사하다고 본다.

시대에 따라서, 상황에 따라서 유동적으로 변하기 때문이다.
그럼에도 기본은 바뀌지않는다.

책을 공동집필 할 때를 떠올려보자
문장과 문단을 다듬어 하나로 매끄럽게 이어지도록 한다.
즉, 글의 문체가 같도록 또는 비슷하게라도 한다는 이야기다.

코드도 마찬가지다.
하나의 거대한 책을 공동 집필 하는 것이다.
외부 라이브러리를 사용할 때에는 인용하는 것 처럼 외부 코드 스타일이 들어오지만
결코 섞이지 않는다. 명백히 다른 스타일을 유지한다.

원점으로 돌아와서 그러면 읽기 힘든 책은 뭘까?
나는 사족이 많은 책이라 생각한다.
사족은 집중력을 깨트리고 독자로 하여금 사족의 의도에 대해서 생각하게 만든다.
그리고 사족임을 깨닫는다.
이는 읽는 당시에는 사족임을 모르기에 읽어봐야만 판단할 수 있기 때문이다.

사족

코드로 한번 봐보자

if(!hasNext()) {
  console.log("has not next!");
}

이 코드를 읽기 위해서는 ! 연산자의 작용을 생각해야한다. 그러고 나서야 hasNext의 반환값이 false일 때 라는 조건을 깨닫게 된다.

이를 서순대로 코드를 적으면 아래와 같다.

if(hasNext() === false) {
  console.log("has not next!");
}

코드가 더욱 더 명시적으로 된 것을 볼 수 있다.

해당 구문만 이야기하고자 하는 것은 아니다. 내가 이야기하고싶은건 생각을 하게 만드는 코드는 최대한 지양하자는 의미다.

다음의 코드를 봐보자

function fn1(targetBoolean: boolean): boolean | null {
  const a: boolean = getCondition();
 
  if(a === true && targetBoolean === false) {
    return true;
  }
 
  if(a === false && targetBoolean === true {
    return false;
  }
 
  return null;
}

간략화하여 그나마 읽을만 하겠지만, 이 또한 생각을 많이하게 만드는 코드다.
인자값인 targetBooleangetCondition()으로 얻은 a를 신경써서 읽어야 한다.
인자값으로 추가 변수들이 들어와서 getCondition()으로 들어온다면 추적하기가 더 힘들 것이다.

이를 아래와 같이 변경할 수 있다.

function fn1(targetBoolean: boolean): boolean | null {
  const a: boolean = getCondition();
 
  if(a === targetBoolean) {
    return null;
  }
 
  if(a) {
    return true;    
  }
  
  return false;
}

return a;를 하지 않은 이유는 실제로는 로직이 들어가기 때문이다.
이렇게 된다면 분기처리 횟수는 같지만 그럼에도 각 분기문에 조건이 줄어들었기 때문에 읽기가 더욱 더 좋아졌다.
이를 혹자는 카디널리티의 감소라고 표현하기도 하며 복잡도 감소라고 부르기도 한다.

Stateful Code

글을 읽을 때 한참 뒤에서 앞에서 언급된 부분을 다시 꺼낸다면 그것이 무엇인지 오래 생각을 하거나 다시 찾으러 가야만 한다.
글을 이해하기 위해 찾으러 갈 수 밖에 없는 것이다.

반복문 사이에 여러 변수들을 끼워놓고 각 루프마다 그 값들이 참조되어 값이 바뀐다고 하자
그렇다면 이게 글로별 변수랑 뭐가 다른가?

글로벌 변수는 되도록 자제하라는 이야기를 많이 들었을 것이다.
그 이유도 대부분은 "유지 보수가 안된다." 또는 "추적하기가 힘들다." 라는 이야기다.

상태변수를 사용하는 것도 같은 맥락이다.

let hasTrue = false;
const array = [false, false, false, true, false];
 
for(const item of array) {
  if(item) {
    hasTrue = true;
  }
}
 
return hasTrue;

위의 예제 코드처럼 작성하게 된다면 우리는 분기문을 보고있다가 다시 뒤로 돌아가서 item이 뭔지, item이 어디서부터 왔는지를 확인하러 가야한다.

const array = [false, false, false, true, false];
return array.some(item => item === true);

array에 true가 있는지 확인하는 코드가 확연히 보인다.
물론 이도 말이 많을 것이다. 코드를 읽는 독자 모두가 some에 대해서 알고 있어야 하기 때문이다.

하지만 모두가 충족하고 있다면 충분히 좋은 코드가 될 수 있다.
예제에서는 some 같은 빌트인 메서드를 사용하였지만
여러분이 마주한 것은 외부 라이브러리일 것이다.
팀원들을 이끌어야한다는 이야기며, 팀원들이 모른다면 그건 좋은 코드가 될 수 없다.

독자를 충분히 신경 쓰지못한 코드가 되기 때문이다.