모든 글

모든 조회를 삼키는 만능 메서드를 목적별로 쪼개라

만능 동적 조회를 목적별 메서드로 나누고 호출부를 점진적으로 옮겨, 리팩터링의 사이드 이펙트를 줄입니다.

출처 및 AI 안내: 이 글은 제미니의 개발실무 유튜브를 기반으로 작성되었습니다. gpt-5.6-sol 모델을 사용해 생성·편집했습니다.

모든 동적 조회를 처리하는 메서드는 호출 목적이 드러나는 여러 메서드로 나눠야 한다. 많은 조건을 담은 범용 객체를 받고 모든 업무 흐름을 지원하면 의도가 사라진다. 테스트가 없는 상태에서 조건 하나를 바꿀 때 관련 없는 호출부까지 사이드 이펙트 범위에 들어온다.

범용성은 모든 변경을 전역 문제로 만든다

선택 조건이 많은 리포지토리 메서드는 재사용하기 좋아 보인다. 호출부마다 필요한 값만 넘기고 구현 한 곳이 모든 쿼리 조합을 만든다. 인터페이스의 단순함 대신 긴 조건 분기 안으로 복잡성을 옮긴 것이다.

나중에 특정 업무의 조건 하나만 고치려 해도 어느 호출부가 그 분기에 기대는지 이름으로 알 수 없다. 동적인 입력 조합까지 겹치면 한 흐름의 요구가 모든 사용처를 조사해야 하는 일이 된다.

널 가능한 필드가 잔뜩 있는 SearchParam 같은 객체는 문제를 더 키운다. 호출 이유가 어떤 값이 있고 없는지 뒤에 숨는다.

목적별 메서드는 쿼리의 이유를 보이게 한다

회원 탈퇴를 위한 조회라면 그 업무가 드러나는 이름을 쓰고 필요한 필드만 받는다. 가입이나 다른 흐름의 조건과 이유가 다르다면 별도 메서드로 둔다. 구체적인 용어는 도메인에 맞추되, 메서드만 봐도 이 쿼리가 왜 존재하는지 알 수 있어야 한다.

목적별 메서드를 좁게 유지하고 모든 조회를 다시 하나의 만능 입구로 보내지 않는다.

내부를 고치기 전에 영향 범위를 좁힌다

널리 쓰이는 레거시 메서드를 한 번에 다시 작성하지 않는다. 호출부 하나를 골라 현재 사용하는 동작을 복사하고, 그 경로에서 늘 널이던 파라미터를 없앤다. 새 메서드로 호출을 옮긴 뒤 분리 자체를 먼저 배포한다.

이 단계에서는 복사한 쿼리를 그대로 둬도 된다. 첫 목표는 이후 수정이 미치는 범위를 줄이는 것이다. 호출부를 분리한 뒤 다음 이터레이션에서 작아진 메서드를 정리한다.

시스템이 움직이는 동안 작은 리팩터링을 합친다

개인 브랜치에서 몇 달 동안 전부 고치는 사이 동료들은 기존 만능 메서드에 새 호출을 더한다. 작은 변경을 자주 머지하면 기본 경로가 빨리 바뀐다. 목적별 메서드 하나가 생긴 순간부터 새 작업은 그쪽을 쓰고 다음 호출부를 이어서 옮길 수 있다.

목표는 개인 브랜치에서 몇 달 동안 전체를 다시 쓰는 것이 아니다. 목적 하나를 나누고 머지해 배포한 다음 다음 부분을 이어서 정리한다. 목적별 메서드를 두면 모든 업무가 같은 만능 분기판에 의존하지 않아도 된다.