이 코드… 뭐야?

 

 

 

 

첫 업무를 받았다. “이 API에 필드 하나 추가해줘.”

파일을 열었다. 코드 1,200줄. 주석 없음. 변수명 tmp, data1, result2…
함수 하나가 200줄?
if문 5단 중첩?
for문이 3단?

 

‘누가 이렇게 짠 거야? 이걸 어떻게 이해하지?’

스크롤을 내린다. 올린다. 다시 내린다. 아무것도 이해가 안 된다.

 

‘어디에 필드를 추가해야 하지? 이 함수는 뭘 하는 거지? 이 변수는 왜 여기 있지?’ 슬슬 당황을 넘어 두려워 지기 시작한다. 괜찮다. 레거시 코드는 원래 그렇다. 신입만 어려운 게 아니다. 시니어도 어렵다. 그래서 레거시 코드를 읽는 요령을 정리했다.

 

 


 

 

레거시 코드가 뭔가요?

 

 

레거시 코드(Legacy Code)란 오래전에 작성된 코드를 말한다.

 

보통 이런 특징이 있다:

  • 작성한 사람이 퇴사했거나 기억 못 함
  • 주석이 없거나 오래된 주석
  • 복잡한 구조
  • 테스트 코드 없음
  • 누구도 건드리고 싶어하지 않음

 

왜 레거시 코드가 생기나?

처음엔 잘 짰다. 하지만 시간이 지나면서 변화가 생긴 것이다.

  • 급하게 기능 추가
  • 임시방편으로 버그 수정
  • 여러 사람이 덧붙이기
  • 리팩토링 없이 계속 쌓임

결국 그렇게 잘만들어진 코드가 스파게티처럼 꼬여버리게 된다.

 

레거시 코드는 나쁜 코드인가?

꼭 나쁜것만은 아니다. 레거시 코드는 살아남은 코드다. 몇 년 동안 실제로 쓰이고 있다는 뜻이다. 비즈니스에 핵심적이라는 뜻이다. 복잡한 이유가 있다. 수많은 엣지 케이스를 처리하고 있다. 그냥 보기 안 좋을 뿐 열심히 자기 할일을 하고 있는 셈이다.

 

 


 

 

주석과 커밋 히스토리 활용

 

 

레거시 코드를 읽을 때 가장 먼저 할 일은 이렇다.

 

주석 찾기

우선 주석을 찾아 헤매자, 정성스럽게 주석이 남겨져 있다면 좋은 레거시 코드다.

 

좋은 주석

// 2023-05-12: 결제 실패 시 3번 재시도 (이슈 #1234)
// 주의: 이 함수는 동기 처리해야 함 (비동기 시 데이터 꼬임)

레거시 개발자들에게 감사하자 친절하게 코드를 알려주고 있다. 좋은 주석은 맥락을 알 수 있게 한다.

 

나쁜 주석

// 데이터 조회
// 루프 돌리기

그렇다. 있으나 마나한 내용의 주석은 전혀 도움이 안된다. 내용이 충실하지 않는 주석은 낙서정도로 생각하고 과감히 버리자 오히려 코드 분석을 방해 할때도 있다.

 

 


 

 

커밋 히스토리 보기

 

 

커밋 내역은 시간여행 기계이다. 누가 언제 왜 수정했는지 볼 수 있기 때문이다.

소스를 수정한 이슈 번호가 있으면 더 좋다. 이슈 트래커 가서 찾아보면 당시 상황을 알 수 있기 때문이다.

파일의 변경 이력으로 언제 어떤 기능이 추가됐는지, 언제 버그가 수정됐는지 볼 수 있다.

 

커밋 히스토리가 얼마나 유용한지 그 예시를 들기 위해 스토리를 한번 만들어봤다.

 

파일을 열었다. 함수 하나가 300줄이다. 중간에 이상한 조건문이 있었다. 로직은 금액이 100 미만일 때문 다르게 처리하게 되어 있었다. 당연히 주석은 없었다. 그래서 커밋 히스토리를 살펴봤다. 커밋 메시지는 이슈 트래킹 번호를 메세지로 남겼고 “Fix issue #567” 이슈 트래커 따라 가서 해당 이슈를 확인했더니 “100원 미만 결제 지원 안 함. 처리 필요” 라고 내역을 확인할 수 있었다. 만약 커밋 히스토리가 없었다면 이 코드 의미는 평생 몰랐을 수도 있었을 것이다.

 

 


 

 

일단 전체 흐름 파악 후 세부 사항

 

 

레거시 코드를 읽을 때 가장 큰 실수는 한 줄 한 줄 다 이해하려고 하는 것.

 

숲을 먼저 보고 나무는 나중에

잘못된 접근 1줄, 2줄, 3줄 차례대로 읽기 이렇게 너무 세세하게 한줄 한줄 읽다보면 금방 하루가 지나간다. 그리고 지친다. 효과적인 코드를 읽는 방법을 말해보겠다.

올바른 접근

  • 전체 흐름 파악 (10분)
  • 중요한 부분만 세부 파악 (30분)
  • 필요 없는 부분은 건너뛰기

 

전체 흐름 파악하는 법

코드는 건너뛰고 함수 이름만 쭉 읽는다. 함수명과 주석만 쭉 읽어보자. 예를 들면 이렇다.

getUserData() validateUser() fetchPaymentInfo() processPayment() sendConfirmation()

‘아, 사용자 데이터 가져오고, 검증하고, 결제 처리하고, 확인 보내는구나.’ 이렇게 전체 그림을 확인 할 수 있다.

 

엔트리 포인트부터 따라가기

제일 처음 호출되는 함수부터 시작하는 방법이다. 예를 들면 이렇다.

main() -> handleRequest() -> processOrder() -> calculatePrice() -> createInvoice()

이렇게 처음 시작되는 부분부터 차례대로 분석 해보자.

 

디버거 활용

브레이크포인트 걸고 실행해보자. 어떤 순서로 함수가 호출되는지 눈으로 볼 수 있다. 코드를 읽는 것보다 디버거를 통해 코드를 분석하는게 10배는 빠르다고 생각한다.

 

세부 사항은 필요할 때만

전체 흐름 파악했으면, 이제 내가 수정할 부분만 자세히 본다.나머지는 “지금은 몰라도 됨” 상태로 남겨둔다. 괜찮다. 다 이해할 필요 없다. 어차피 차차 알아갈 테니깐

“페이지 로딩 속도 개선”이라는 업무를 맡은 적이 있다. 그래서 해당 부분의 코드를 열었다. 파일 5개, 총 2,000줄. 처음에는 미련하게 전체 코드부터 1줄씩 읽어갔다. 시간만 가고 진척이 없던걸 깨달았다. ‘이렇게 하면 언제 다 읽지?’ 그래서 방법을 바꿨다. 함수 이름만 쭉 읽었다. 그리고 디버거 걸고 실행하고 데이터 가져오는 부분의 함수를 자세히 봤다. 문제를 발견 했고 DB 쿼리를 나눠서 5번 날리더걸 1번으로 합치게 되었다. 코드를 보는 것도 요령이 있어야 하는 것을 깨닫게 되었다.

 

 


 

 

이해 안 되는 부분은 선배에게 질문하자.

 

 

혼자 고민하지 말자. 레거시를 당신보다 오랫동안 분석 해온 선배가 옆자리에 있다.

 

15분 룰

이해 안 되는 코드 있으면? 일단 15분 혼자 고민해본다.

  • 주석 찾기
  • 커밋 내역 보기
  • 이슈 트래커 검색
  • 구글 검색

15분 지나도 모르겠으면? 물어봐라. 더 고민해봤자 시간 낭비다. 지름길을 안내받자.

 

레거시 코드 질문 잘하는 법

  • 나쁜 질문 : “이 코드 무슨 뜻이에요?” 너무 막연하다. 선배도 어디서부터 설명해야 할지 모른다.
  • 좋은 질문 : “이 코드에서 왜 한국일 때만 다르게 처리하나요? 특별한 이유가 있나요?” 구체적이다. 선배가 답하기 쉽다.
  • 더 좋은 질문 : “이 코드가 한국 결제 게이트웨이 제한 때문인 것 같은데, 맞나요? 커밋 내역을 보니 이슈 #567이 연관된 것 같은데 확인이 필요할까요?” 추측과 근거를 제시한다. 선배가 “맞아, 그거야” 하고 바로 확인해준다.

 

작성자 찾기

그 코드를 직접 작성한 개발자에게 물어보는 방법은 꽤나 효율적이다. 수정 내역을 보고 마지막 해당 부분을 수정한 동료를 찾아가 “이 부분 작성하신 거 맞죠? 질문 하나만 해도 될까요?” 라고 물어보자 본인이 쓴 코드라 누구보다 잘 알 것이다.

 

작성자가 퇴사했으면?

해당 퇴사자에게 인수인계 받은 사람에게 물어보자. 찾기 어렵다면 팀장님에게 물어보자. 그래도 여의치 않으면 어쩔 수 없다. 내가 직접 파헤쳐볼 수 밖에.

 

실전 팁

레거시 코드는 회사가 가진 집단 지성이다.
그러므로 혼자 이해하는 게 아닌 팀의 지식으로 이해하는 거다

한번은 코딩중 이상한 변수명을 발견했다. `magicNumber = 17` 왜 17이 고정 값이지? 당연히 주석 없음 커밋 메시지도 “update logic” 이게 끝이었다. 그래서 시니어에게 물었다. “이 17이 뭔지 아세요?” 시니어가 잠깐 생각하더니 말했다. “아, 그거. API 재시도 횟수야. 근데 왜 17인지는 나도 몰라.” 옆자리 다른 시니어가 끼어들었다. “예전에 팀장님이 짠 건데, 원래 10이었어. 근데 장애 한번 나고 나서 넉넉하게 20으로 올렸다가, 너무 많다고 17로 타협한 거야. 팀장님 행운의 숫자래 웃기지?” 그렇다 일부 레거시 코드의 비밀은 어떤 이에 머리속에만 있기도 하다.

 

 


 

 

레거시 코드 읽기 실전 전략

 

 

1단계: 5분 둘러보기

  • 파일 열고 쭉 스크롤.
  • 얼마나 복잡한지 감 잡기.
  • 함수명들 눈으로 훑기.

 

2단계: 주석과 Git 확인 (10분)

  • 주석 있으면 읽기.
  • 이상한 부분 있으면 Git Blame.
  • 커밋 메시지 확인.

 

3단계: 전체 흐름 파악 (15분)

  • 함수 호출 순서 파악.
  • 큰 그림 그리기.
  • 디버거 활용.

 

4단계: 필요한 부분만 세부 파악 (30분)

  • 내가 수정할 부분만 자세히 보기.
  • 나머지는 건너뛰기.

 

5단계: 막히면 질문 (15분 룰)

  • 15분 고민해도 모르겠으면 물어보기.
  • 시간 아끼기.

 

 


 

 

체크리스트: 레거시 코드 읽기

 

 

주석과 히스토리

  • 주석 읽었는가?
  • Git 내역으로 작성자 확인했는가?
  • 커밋 메시지 확인했는가?
  • 관련 이슈 찾아봤는가?

 

전체 흐름

  • 함수 호출 순서 파악했는가?
  • 전체 로직 큰 그림 그렸는가?
  • 디버거로 실행 흐름 확인했는가?

 

세부 파악

  • 내가 수정할 부분 위치 알았는가?
  • 해당 부분 세부 로직 이해했는가?
  • 테스트 방법 알았는가?

 

질문

  • 15분 룰 지켰는가?
  • 구체적으로 질문 준비했는가?
  • 작성자 또는 시니어에게 물어봤는가?

 

 


 

 

레거시 코드는 무서운 게 아니다

 

 

레거시 코드는 신입 개발자를 공포에 떨게하는 그런 무서움 존재다. ‘이걸 어떻게 이해하지? 이걸 건드렸다가 뭐가 깨지면 어떡하지?’ 라는 막연한 두려움을 준다. 그런데 괜찮다. 사실 레거시 코드는 그냥 낡은 코드일 뿐이다.

 

천천히 시도해보자 그리고 선배에게 물어보자 디버깅도 해보고 그렇게 다양하게 레거시와 씨름하다보면 익숙해져간다. 그리고 중요한 건, 레거시 코드 읽는 능력은 정말 중요한 스킬이라는 것. 신입 때 배워두면 평생 써먹는다. 왜냐하면, 모든 회사에 레거시 코드가 있다. 그리고 그 레거시 코드에게 감사하자 당신은 그 레거시 코드 덕분에 그 회사에 취직 한 것이다.

 

 


고코더 님이 브런치에 게재한 글을 편집한 뒤 모비인사이드에서 한 번 더 소개합니다.