레거시 코드
오래된 건물의 벽 속에 얽힌 배관 같아서, 건드리면 어디서 물이 샐지 모르는 코드예요.
정의 오래전에 만들어져 지금도 사용 중이지만, 너무 낡고 복잡해서 수정하기 두려운 소프트웨어 코드를 말해요. 개발자 마이클 페더스(Michael Feathers)는 '테스트 코드가 없는 코드'를 레거시 코드로 정의하기도 했어요. 겉으로는 정상 작동해도 시간이 지나면서 새로운 기능을 추가하거나 버그를 고치기 점점 더 어려워져요.
왜 손대기가 무서울까요?
수십 년 된 낡은 집을 리모델링하려고 벽을 뜯었다가, 알 수 없는 전선들이 거미줄처럼 얽혀 있어 당황하는 모습을 상상해 보세요. 벽돌 하나를 잘못 뺐다가는 집 전체가 흔들릴 수도 있어요.
레거시 코드가 바로 이런 상태예요. 처음 프로그램을 만든 사람은 이미 퇴사했고, 설명서(문서화)도 제대로 남아 있지 않은 경우가 많아요. 지금 당장은 프로그램이 굴러가지만, 코드 한 줄을 수정했을 때 전혀 상관없어 보이는 다른 기능이 갑자기 멈출 위험이 커요.
그래서 개발자들은 문제가 생겨도 근본적인 수리를 꺼리고, 그 위에 땜질식 코드를 덧붙이곤 해요. 이런 땜질이 반복되면 코드는 점점 더 손대기 힘든 괴물로 변해버려요.
조금 더 정확히 말하면
단순히 작성된 지 오래되었다고 해서 무조건 레거시 코드인 것은 아니에요. 10년 전에 짠 코드라도 구조가 깔끔하고 문서화가 잘 되어 있으며, 자동 검증 장치(테스트 코드)가 든든하게 받쳐주고 있다면 좋은 코드예요.
전문가들이 레거시 코드를 구분하는 가장 핵심적인 기준은 바로 자동화된 테스트의 유무예요. 테스트 코드는 내가 수정한 내용이 기존 기능을 망가뜨리지 않았는지 버튼 하나로 확인해 주는 안전장치예요.
이 안전장치가 없다면 코드를 고칠 때마다 사람이 일일이 모든 기능을 눌러보며 확인해야 해요. 결국 불안감 때문에 누구도 코드를 개선하지 못하고 기술적 빚(기술 부채)만 눈덩이처럼 불어나게 돼요.
레거시 코드는 어떻게 다뤄야 할까요?
가장 흔히 하는 실수는 '처음부터 다 뜯어고치자'며 시스템을 통째로 다시 만드는 거예요. 하지만 기존 시스템이 수년간 버텨온 수많은 예외 상황과 노하우를 한 번에 새로 구현하는 일은 생각보다 훨씬 위험하고 실패 확률도 높아요.
대신 정원사가 가지를 치듯 조금씩 안전하게 다듬는 리팩터링 방식을 써요. 건드려야 하는 아주 작은 부분에 먼저 안전망(테스트 코드)을 씌우고, 그 부분의 코드 구조만 알기 쉽게 정리하는 작업을 매일 반복하는 것이죠.
이렇게 서서히 낡은 부품을 새 부품으로 갈아 끼우다 보면, 멈추지 않고 달리는 자동차의 엔진을 교체하듯 시스템 전체를 안전하고 건강하게 유지할 수 있어요.
🤔 흔한 오해
레거시 코드는 그냥 낡고 오래전에 짠 코드다.
작성 시기와 상관없이, 테스트 코드가 없거나 구조가 얽혀 수정하기 두려운 코드가 레거시 코드예요. 어제 짠 코드도 테스트가 없고 엉망이라면 레거시 코드가 될 수 있어요.
🧺 일상에서 만나요
레거시 코드는 안전장치와 설명서가 없어 수정하기 두려운 코드이며, 작은 테스트와 점진적인 리팩터링으로 극복해야 해요.