쳬계 없는 코드
쇼핑몰 인수인계를 받던 날, 프로모션 기능 파일을 열었다. 스크롤바가 실처럼 가늘었다. 3만 줄이 넘는 코드였다.
'프로모션이 많았나 보다.' 처음엔 그렇게 생각했다. 코드를 읽기 시작하면서 이상함을 느꼈다. 같은 패턴이 반복됐다. 할인 계산 로직이 여러 곳에 흩어져 있었다. 쿠폰 적용 기능이 중복됐다. 적립금 처리는 여러 곳에서 각각 다르게 구현돼 있었다.
며칠간 파일을 뒤졌다. 이건 복사와 붙여 넣기로 만들어진 코드였다. 상품 리스트 화면 만들 때 할인 계산을 짰고, 장바구니 화면 만들 때 또 짰고, 주문 화면 만들 때 또 짰다. 조금씩 변형을 줬지만 본질은 같았다.
할인율이 바뀌면 여러 군데를 찾아 고쳐야 했다. 한 곳이라도 놓치면 버그가 생겼다. 실제로 그랬던 것 같았다. 같은 상품인데 어떤 페이지에서는 10% 할인이 적용되고, 어떤 페이지에서는 적용되지 않았다.
인수인계 문서에는 파일만 기재되어 있었다. 프로모션은 쇼핑몰의 핵심 기능이다. 시즌마다 바뀌는 할인율, 특정 상품 쿠폰, 회원 등급별 적립금. 가장 자주 수정되는 부분인데 인수인계에는 파일명만 있었다. 이전 개발자도 이 코드를 감당하지 못했던 것이다. 설명할 수 없으니 넘겼던 것이다.
80년대엔 코드를 길게 짜는 게 실력이었다. 줄 수가 많을수록 복잡한 걸 만들었다는 증거였다. 지금은 반대다. 같은 기능을 짧게 짤수록 좋은 코드다. 중복을 없애고, 재사용 가능하게 만드는 게 실력이다. 3만 줄짜리 파일은 실력이 없다는 증거다.
이유는 명확하다. 화면설계서 전체를 보지 않았거나 어느 누구도 3만 줄 파일을 한 번도 분석하지 않았다는 것. 전체 또는 파일을 봤다면 분석할 수 있었을 것이다. 프로모션이 어느 화면에 적용되는지, 할인 계산이 어디서 필요한지. 분석했다면 분해할 수 있다. 큰 기능을 작은 단위로 나누고, 반복되는 부분을 찾아낼 수 있다. 분해했다면 공통화할 수 있다. 함수 하나로 만들어 여러 곳에서 쓸 수 있다.
하지만 이 코드엔 그런 과정이 없었다. 눈앞의 화면 하나만 보고 코드를 짰다. 체계 없이 만든 코드는 이렇게 3만 줄이 됐다.
결국 새 파일을 만들기로 했다. 수정하는 것보다 처음부터 다시 짜는 게 나았다.
화면설계서 전체를 펼쳤다. 100페이지가 넘는 분량을 처음부터 끝까지 읽었다. 프로모션이 적용되는 모든 화면을 찾았다. 할인 계산은 상품 리스트, 상세, 장바구니, 주문, 결제 다섯 곳에서 쓰였다. 쿠폰 적용은 두 곳, 적립금은 네 곳이었다.
새로 만든다고 해도, 기존 코드의 로직은 가져와야 한다. 3만 줄짜리 코드를 분석했다. 우선 코드 정리가 필요했다. 같은 기능을 하는 메소드는 파라미터로 통합하고, 같은 맥락의 변수는 하나로 합쳤다.
기능을 최소 단위로 나눴다. 기본 할인율 적용, 쿠폰 할인, 회원 등급 할인, 적립금 적용, 최종 금액 산출. 각각을 함수로 만들었다. 어디서든 불러 쓸 수 있게. 시즌 할인율이 바뀌면 함수 하나만 고치면 됐다.
코드는 천 줄로 줄어들었다. 기능은 그대로였다. 각 함수가 무슨 일을 하는지 이름만 봐도 알 수 있었다. 2주 걸렸다. 기존 파일을 고쳤다면 한 달은 걸렸을 것이다.
개인적으로 파일 하나의 천 줄도 많다고 생각한다. 일만 줄이 넘으면 보기도 힘들고 고치기는 거의 불가능하다. 3만 줄은 관리 불가능한 수준이다. 인수인계조차 할 수 없는.
자료구조를 모르면 데이터 흐름이 보이지 않는다. 분석할 수 없고, 분해할 수 없고, 공통화할 수 없다. 같은 기능을 여러 번 만들게 되고 한 파일이 무한정 길어진다. 오류는 없는데 결과가 이상할 때 디버그를 한다. 프로그램 실행 과정을 하나하나 따라가며 어디서 잘못됐는지 찾는 작업이다. 3만 줄짜리 파일에서 디버그를 하면 하루가 가도 원인을 못 찾을 때가 있다.
이 사건으로 세 가지를 알 수 있다. 화면설계서 전체를 봐야 체계를 만들 수 있다는 것. 분석하고, 분해하고, 공통화하는 과정이 제대로 된 코드를 만든다는 것. 그리고 제대로 만든 코드만이 인수인계가 가능하다는 것. 엉망인 코드는 설명조차 할 수 없다.
프로젝트에 투입되면 개발 전에 화면설계서를 처음부터 끝까지 읽어야 한다. 비슷한 기능끼리 표시하고, 공통으로 뺄 수 있는 부분을 메모한다. 시간이 걸려도 한다. 그 시간이 나중에 3만 줄을 다시 짜는 시간을 막아준다. 다음 사람에게 제대로 인수인계할 수 있게 만든다.
전체를 보지 않으면 체계를 만들 수 없다. 체계 없이 짠 코드는 3만 줄짜리 쓰레기가 된다.
이런 땜빵식으로 만들어진 코드나 진행은 쓰레기를 양성하고, 더 많은 비용을 감당해야 한다.