개발 slecs

기술 부채 정리로 코드 구조와 유지보수성 개선

목차

PublicAttachController를 제거하면서 연관된 뷰 템플릿, 프론트엔드 스크립트까지 함께 정리했다. 기능 변경은 전혀 없고, 수정 파일은 3개다. 결과만 보면 소박하지만 이 작업을 미루면 어떤 일이 벌어지는지 이미 경험했기 때문에 일부러 시간을 잡아서 진행했음.


컨트롤러 이름에 Public이 붙어 있으면 보통 인증 없이 접근 가능한 엔드포인트를 담는다고 암묵적으로 기대하게 된다. 그런데 실제로 들여다보면 Attach 관련 처리가 반쯤 거기 있고 반쯤은 다른 컨트롤러에 분산돼 있는 상황. 새 기능을 붙이려고 할 때마다 "이거 어디다 넣어야 하지?"를 매번 고민하게 만드는 코드였음.

이런 상황이 생기는 이유는 보통 단순하다. 처음에는 맞는 위치였는데 요구사항이 바뀌면서 역할이 흘러넘쳤거나, 빠르게 출시하면서 "일단 여기다 넣자"를 반복한 결과다. 코드 자체가 틀린 게 아니라 맥락이 달라진 것. 그래서 버그가 아닌 기술 부채라고 부르는 거고.

이번 정리의 범위와 기준

리팩토링할 때 제일 먼저 결정해야 하는 건 범위다. 한 번에 너무 많이 건드리면 검증이 힘들고, 어디서 문제가 생겼는지 추적하기도 어려워진다. 이번엔 논리적으로 묶이는 것들만 같이 처리하는 방식으로 진행했음.

  • 컨트롤러: 역할이 불명확한 부분을 분리. PublicAttachController가 담당하던 로직을 실제 소유권이 있는 쪽으로 이동.
  • 뷰 템플릿: 동일한 렌더링 로직이 여러 곳에 흩어져 있었던 걸 통합.
  • 프론트엔드 스크립트: 같은 개념을 지칭하는 이름이 파일마다 달랐던 것을 일관되게 정리.

변경 유형별로 정리하면 이렇다.

변경 유형 건수
중복 제거 다수
이름 변경 다수
파일 삭제 일부
수정 파일 합계 3개

수정 파일 합계가 3개라는 숫자가 중요하다. 영향 범위를 의도적으로 좁게 유지했다는 뜻이기도 하고, 변경 후 검증할 때 어디를 집중적으로 확인해야 하는지도 명확해진다.

리팩토링할 때 실제로 쓰는 패턴

주석으로만 남겨두는 것보다 변경 의도를 커밋 단위로 분리하는 게 나중에 git log를 봤을 때 훨씬 유용하다. 이번 작업도 아래 네 가지 유형으로 나눠서 처리했음.

// 제거: 사용하지 않는 dead code - 더 이상 호출되지 않는 메서드, 참조 없는 변수
// 이동: 공통 로직을 적절한 위치로 - 소유권이 맞는 쪽으로 책임 재배치
// 이름 변경: 의도가 드러나도록 - 구현 방식이 아닌 역할 기준으로
// 분리: 너무 큰 모듈을 적절한 크기로 - 단일 책임 원칙 기준

dead code 제거는 겁이 나서 미루는 경우가 많다. "혹시 어딘가에서 쓰고 있지 않을까"라는 불안 때문에. 근데 IDE의 참조 검색이나 grep으로 확인이 됐는데도 못 지우겠다면, 그건 코드가 아니라 테스트 커버리지 문제다. 사용 여부를 코드 레벨에서 추적할 수 없는 상태가 더 큰 문제임.

이름 변경도 마찬가지로 미루기 쉬운 작업인데, 사실 비용 대비 효과가 제일 큰 리팩토링 유형 중 하나다. data, info, manager, util 같은 이름들은 아무 정보도 주지 않는다. PublicAttachController라는 이름이 왜 문제였냐면, Public이라는 접두사가 접근 제어 의미인지 네이밍 관례인지 불분명했기 때문임. 코드를 읽는 사람이 이름에서 의도를 읽어낼 수 없다면, 그 이름은 오해를 만드는 주석과 다를 바 없다.

구조를 바꿨을 때 실감한 것들

변경 후 기존 기능 동작 확인했음. 그리고 정리 전후를 직접 비교해보면 효과가 꽤 구체적으로 느껴진다.

효과 체감 수준
코드 탐색 시간 줄었음
수정 범위 명확성 향상됨
버그 발생 가능성 낮아짐

특히 탐색 시간 변화가 실질적으로 느껴지는 부분이다. 이전에는 Attach 관련 뭔가를 수정하려면 여러 파일을 순서 없이 뒤지는 과정이 있었는데, 정리 후에는 어디를 봐야 하는지 바로 알 수 있게 됐음. 이 시간 절약이 하루에 몇 분이어도, 몇 달 동안 쌓이면 꽤 된다.

기술 부채를 이자에 비유하는 표현이 있는데, 이번에 또 실감했음. 이자가 무서운 이유는 원금보다 이자가 커지는 시점이 오기 때문이다. 코드도 비슷하다. 정리가 미뤄질수록 연관된 코드가 그 구조에 맞춰져버리기 때문에 나중에 손댈 때의 범위가 계속 커진다. 3개 파일로 끝난 이번 작업도 한 달 더 미뤘다면 범위가 달라졌을 거임.

코드는 처음부터 완성된 상태로 만들 수 없다. 요구사항이 바뀌고, 팀의 이해도도 달라지고, 시스템 규모도 변한다. 지금의 구조가 맞다고 판단해서 만들었어도 6개월 후에는 다른 결정이 맞을 수 있다. 그래서 리팩토링은 실패의 정정이 아니라 자연스러운 개발 주기의 일부라고 생각함. "완성된 코드"라는 개념 자체가 없는 거고, 지금 이 순간의 요구사항과 이해도에 가장 잘 맞는 코드가 있을 뿐이다.

댓글 0

첫 댓글 달아줘.