페이지빌더 뷰·스크립트 리팩토링으로 유지보수성 개선
목차
기술 부채를 아예 안 쌓는 팀은 없다고 생각한다. 쌓이는 속도를 늦추거나, 쌓인 걸 주기적으로 털어내거나 - 두 가지 중 하나다. 이번 작업은 후자 쪽이었음. 페이지빌더 관련 뷰와 스크립트를 정리했는데, 기능 변경은 없고 내부 구조만 손댔다.
왜 지금 정리했나
기능 추가나 버그 수정 작업을 하다 보면 "이 코드 언제 한 번 제대로 고쳐야 하는데"라는 생각이 드는 지점들이 생긴다. 그걸 그때그때 주석으로 달아두거나 머릿속에 기억해두는 경우가 많은데, 어느 시점이 되면 그 목록이 너무 길어져서 오히려 부담이 된다. 페이지빌더 쪽이 딱 그 상태였음.
문제가 됐던 지점은 세 군데였다.
- 뷰 템플릿 일부가 역할 경계가 모호해서, 어디까지가 레이아웃이고 어디서부터 로직인지 구분이 안 됐음
- 프론트엔드 스크립트에 거의 동일한 로직이 두 군데 이상 흩어져 있었음. 한 곳에서 버그를 고치면 다른 곳도 고쳐야 한다는 걸 한참 뒤에야 알게 되는 패턴
- 뷰 레이어 파일과 변수 이름이 작성자마다 자기 방식으로 만들어져 있어서, 처음 보는 사람은 물론이고 며칠 지나면 본인도 헷갈리는 수준
세 문제 모두 당장 기능에 영향을 주는 건 아니었다. 그런데 그게 오히려 더 위험한 이유가, 아무도 급하게 고칠 이유를 못 느끼기 때문임. 결국 새 기능 붙일 때마다 이 위에 코드가 더 얹히고, 나중엔 손을 댈 엄두가 안 나게 된다. 6개월만 더 미뤘으면 지금보다 훨씬 큰 범위를 건드려야 했을 것 같다.
어떻게 접근했나
리팩토링에서 흔히 하는 실수가 한꺼번에 너무 많이 바꾸는 거다. 범위가 넓어질수록 변경 검증이 어렵고, 뭔가 깨졌을 때 원인을 찾는 시간이 기하급수적으로 늘어난다. 이번엔 논리적으로 연관된 것끼리 묶어서 단계별로 진행했음.
| 변경 유형 | 건수 | 의도 |
|---|---|---|
| 중복 제거 | 다수 | 동일 로직을 단일 출처로 통합 |
| 이름 변경 | 다수 | 역할이 드러나도록 |
| 파일 삭제 | 일부 | 더 이상 호출되지 않는 dead code |
| 수정 파일 합계 | 3개 | - |
커밋도 유형별로 쪼갰다. 하나의 커밋에 "중복 제거 + 이름 변경 + 파일 삭제"를 다 때려넣으면, 나중에 git blame이나 git log 볼 때 변경 맥락을 추적하기가 어려워진다. 유형별로 분리하면 리뷰도 편하고 롤백 범위도 명확해짐.
코드로 표현하면 이런 식의 변화들이었다.
// Before: 두 곳에 흩어진 동일 로직
// widget-editor.js
function buildDragPayload(item) {
return { id: item.id, type: item.type, meta: item.meta };
}
// widget-list.js
function makeDragData(widget) {
return { id: widget.id, type: widget.type, meta: widget.meta };
}
// After: 공통 유틸로 이동
// utils/drag.js
export function buildDragPayload(item) {
return { id: item.id, type: item.type, meta: item.meta };
}
// Before: 의도를 알 수 없는 이름
const data2 = processWidget(raw);
const temp = filterList(data2);
// After: 역할이 드러나는 이름
const normalizedWidget = processWidget(raw);
const visibleWidgets = filterList(normalizedWidget);
두 번째 예시는 사소해 보이지만, 실제로 코드를 읽을 때 차이가 크다. data2나 temp 같은 이름은 "이 변수가 지금 뭘 담고 있는가"를 전혀 알려주지 않는다. 리뷰어는 함수 구현을 다 읽어야 하고, 본인도 3주 뒤엔 똑같이 다시 읽어야 한다. 이름 짓는 데 드는 1분이 나중에 읽는 데 드는 10분을 아끼는 거임.
뷰 레이어 네이밍 통일도 마찬가지 맥락이었다. 어떤 파일은 xxxView.blade.php, 어떤 파일은 xxx-page.blade.php, 어떤 건 그냥 xxx.blade.php - 규칙이 없으니 새 파일을 만들 때마다 어떻게 이름을 붙여야 하는지 고민이 생겼음. 이번에 규칙을 하나로 정리하고 기존 파일명도 맞춰놨다. 이런 류의 작업은 PR 설명 적을 때 "기능 변경 없음, 이름만 바꿈"이라고 명시해두는 게 리뷰어한테도 중요하다. 안 그러면 리뷰어가 로직 변경인 줄 알고 한참 들여다볼 수 있음.
하고 나서 느낀 것
리팩토링의 효과가 즉각 보이지는 않는다. 코드베이스를 자주 보는 사람은 "아, 훨씬 낫다"라고 느끼지만, 숫자로 증명하기는 어렵다. 그래도 작업 며칠 뒤에 같은 부분에 기능을 추가할 일이 생겼을 때 확실히 체감했음. 이전에는 수정 포인트를 찾기 위해 여러 파일을 오가야 했는데, 정리 후에는 어디를 건드려야 하는지 바로 보였다.
| 체감 변화 | 정리 전 | 정리 후 |
|---|---|---|
| 코드 탐색 시간 | 길었음 | 줄었음 |
| 수정 범위 명확성 | 모호했음 | 명확해짐 |
| 중복 수정 리스크 | 있었음 | 없어짐 |
| 버그 발생 가능성 | 상대적으로 높았음 | 낮아짐 |
기술 부채 이자 얘기를 종종 하는데, 진짜 그렇다. 부채 자체는 처음엔 작아 보이지만, 그 위에 새 코드가 쌓일수록 나중에 고칠 때 건드려야 하는 범위가 커진다. 복잡하게 얽힌 의존성을 풀어가며 리팩토링하는 건 단순 정리와 차원이 다른 일임. 이번처럼 3개 파일 수준에서 마무리할 수 있었던 건 일찍 손댔기 때문이지, 오래 두면 절대 이 범위로 끝나지 않았을 거다.
코드를 처음부터 완벽하게 짜는 건 거의 불가능하다고 본다. 요구사항이 바뀌고, 팀 이해도가 달라지고, 시스템 규모도 커진다. 그러면 예전에 맞았던 구조가 맞지 않게 되는 순간이 온다. "완성된 코드"란 게 없다기보다, 지금 시점에 맞는 코드가 있을 뿐이라는 게 요즘 생각임. 주기적으로 다듬는 게 선택이 아니라 그냥 개발의 일부라고 보게 됐다.
댓글 0
첫 댓글 달아줘.