새 회사 첫 출근날, 저장소를 받아서 코드를 처음 열어본 순간이 아직도 생생합니다.
3천 줄짜리 파일 하나에 온갖 로직이 뒤엉켜 있더라고요. 저도 모르게 한숨이 나왔습니다.
“대체 누가 이렇게 짜놨어…”
그런데 몇 달 뒤, 제가 짠 코드를 보던 신입이 똑같은 표정을 짓고 있었어요. 그때 알았습니다. 레거시 코드는 누구 한 명 탓할 문제가 아니라는 걸요.
결론부터 말씀드리면 이렇습니다.
레거시 코드가 욕을 먹는 이유는 코드가 나빠서가 아니라, 그 코드를 짤 때의 맥락이 지워졌기 때문입니다.
오늘은 왜 레거시 코드가 늘 원망의 대상이 되는지, 그 앞에서 어떻게 하면 덜 다치는지 제 경험을 풀어보려고 합니다.
레거시 코드가 뭔가요? 오래된 코드랑 다른가요
먼저 짚고 넘어갈게요. 레거시 코드는 그냥 ’오래된 코드’가 아닙니다.
제가 겪어보니 기준은 하나였어요. 바로 테스트가 없어서 손대기 무서운 코드입니다.
마이클 페더스라는 개발자는 저서 『레거시 코드 활용 전략』에서 레거시 코드를 “테스트 없는 코드”라고 정의했어요. 작성된 지 일주일밖에 안 됐어도, 테스트가 없어서 고칠 때마다 심장이 쫄깃하다면 그게 레거시입니다.
반대로 10년 된 코드라도 테스트가 촘촘하면 마음 편히 고칠 수 있죠.
그러니까 나이가 문제가 아니에요. 핵심은 ’이걸 건드려도 다른 데가 안 터진다’는 확신이 있느냐 없느냐입니다.
레거시 코드는 왜 항상 욕을 먹을까
이유를 정리해보니 크게 세 가지였습니다.
1. 코드를 짠 사람이 회사에 없습니다
왜 이렇게 짰는지 물어볼 사람이 없어요. 주석도 없고 문서도 없으면, 남은 건 코드와 저의 상상력뿐입니다.
2. 맥락이 사라졌습니다
이상하게 꼬인 코드에는 대부분 사연이 있어요. 급한 마감, 이상한 요구사항, 특정 OS 버전의 버그 회피 같은 것들요.
당시엔 최선이었지만, 그 사정은 코드에 남지 않습니다. 남는 건 결과물뿐이라 지금 보면 이해가 안 되는 거죠.
3. 남의 코드는 원래 다 이상해 보입니다
솔직히 이게 제일 큽니다. 제 코드는 흐름이 머릿속에 있으니 자연스럽지만, 남의 코드는 그 흐름을 처음부터 따라가야 하거든요.
그 답답함이 “왜 이렇게 짰지”라는 말로 튀어나오는 겁니다.
아래 코드를 한번 볼게요. 언뜻 보면 왜 이런 조건이 붙었나 싶은 전형적인 레거시 흔적입니다.
// 왜 30을 빼는지 아무도 모른다
if user.type == "B" && amount > 0 {
finalPrice = amount - 30 // 2019년 프로모션 잔재?
}
이 - 30이 지금도 필요한 건지, 옛날 이벤트의 흔적인지 알 길이 없습니다. 이런 코드 한 줄이 쌓이고 쌓여서 레거시가 됩니다.
그래서 레거시 코드, 어떻게 대해야 하나요
낯선 레거시 앞에서는 “싹 다 갈아엎자”는 마음이 들기 마련이지만, 그보다 나은 길이 있습니다.
제가 지금 지키는 원칙은 세 가지예요.
- 함부로 다시 짜지 않는다 — 돌아가는 코드에는 그동안 잡아온 수많은 버그 대응이 녹아 있습니다. 새로 짜면 그걸 처음부터 다시 겪어야 해요.
- 고치기 전에 테스트부터 씌운다 — 지금 동작을 테스트로 고정해두면, 고친 뒤 뭐가 깨졌는지 바로 보입니다.
- 왜 고쳤는지 흔적을 남긴다 — 커밋 메시지나 주석에 이유를 적어두면, 다음 사람은 최소한 저를 덜 원망합니다.
특히 세 번째가 중요하더라고요. 제가 지금 겪는 답답함을, 미래의 누군가에게 물려주지 않는 유일한 방법이거든요.
결국 오늘의 새 코드도 내일의 레거시
제가 6개월 동안 깨달은 건 조금 허무합니다. 지금 제가 정성껏 짠 이 코드도, 몇 년 뒤엔 누군가에게 욕먹을 레거시가 된다는 거예요.
그걸 인정하고 나니 마음이 편해졌습니다. 완벽하게 짜려고 애쓰기보다, 다음 사람이 덜 고생하게 배려하는 쪽으로 방향을 튼 거죠.
혹시 지금 낯선 레거시 코드 앞에서 한숨 쉬고 계신다면, 그 코드를 짠 사람도 그날의 최선을 다했다는 걸 한 번쯤 떠올려 보세요. 그리고 조용히 테스트부터 씌워봅시다. 그게 서로에게 덜 상처 주는 길이더라고요.
