jaehunby J

구현 상세 추상화하기

2026년 5월 31일

비유: “왼쪽으로 10걸음 걸어라"

"왼쪽으로 10걸음 걸어라”는 금방 이해된다. 이걸 추상화 없이 풀면 이렇게 된다.

북쪽을 바라보았을 때 한 번의 회전을 360등분한 각의 90배만큼 북반구에서 해시계의 바늘이 돌아가는 방향으로 돌아서, 동물이 육상에서 다리를 이용해 움직이는 가장 빠른 방법보다 느린, 신체를 한 지점에서 다른 지점으로 옮겨가는 행위를 10번 반복해라.

뜻은 같지만 전혀 이해가 안 된다. 코드도 마찬가지다.

냄새 나는 코드

function LoginStartPage() {
  useCheckLogin({
    onChecked: (status) => {
      if (status === "LOGGED_IN") {
        location.href = "/home";
      }
    }
  });
  /* ... 로그인 관련 로직 ... */
  return <>{/* ... 로그인 관련 컴포넌트 ... */}</>;
}

”이미 로그인됐으면 홈으로 보낸다”라는 한 문장의 기능인데, 읽는 사람은 useCheckLogin, onChecked, status, "LOGGED_IN" 네 개의 맥락을 한꺼번에 머리에 올려야 한다.

고친 코드: 책임을 Wrapper로 옮기기

function App() {
  return (
    <AuthGuard>
      <LoginStartPage />
    </AuthGuard>
  );
}
 
function AuthGuard({ children }) {
  const status = useCheckLoginStatus();
  useEffect(() => {
    if (status === "LOGGED_IN") location.href = "/home";
  }, [status]);
  return status !== "LOGGED_IN" ? children : null;
}
 
function LoginStartPage() {
  /* ... 로그인 관련 로직 ... */
}

LoginStartPage는 이제 “로그인 페이지”라는 한 가지 책임만 남는다. “이미 로그인됐는지 체크”는 AuthGuard라는 이름 뒤로 숨었다.

[!tip] HOC(withAuthGuard) 패턴도 같은 효과를 낸다. 선택은 팀 컨벤션에 맞추면 된다.

또 다른 신호: 함수가 너무 많은 맥락을 들고 있을 때

<FriendInvitation> 컴포넌트가 “쿼리 조회 + 다이얼로그 열기 + 동의받기 + 푸시 전송”을 전부 한 함수에서 하고 있다면, 이건 여러 책임이 한 곳에 뭉쳐 있다는 신호다. 버튼+핸들러를 <InviteButton>으로 빼내면 읽는 거리가 가까워지고 가독성/응집도가 함께 좋아진다.

언제 추상화하지 말아야 할까

  • 추상화된 이름이 원본보다 덜 명확할 때
  • 한 번만 쓰이고 짧을 때 (3줄짜리 함수를 굳이 뺄 필요 없음)
  • 추상화한 후 점점 인자가 많아지고 조건이 붙을 때 → 오히려 결합도↑

실습 가이드

액션 1: 맥락 수 세기

내 컴포넌트 하나를 골라, 한 함수가 몇 개의 서로 다른 맥락을 다루는지 적어보자.

예시 맥락 유형체크
인증/권한 검사
데이터 쿼리
UI 상태 관리
외부 이벤트 로깅
모달/다이얼로그 띄우기
폼 검증

7개 넘으면 추상화 여지가 있다.

액션 2: Wrapper 컴포넌트 패턴 익히기

직접 <AuthGuard> 비슷한 Wrapper를 만들어보자:

  1. 빈 Next.js 혹은 Vite React 프로젝트를 하나 만든다
  2. useCheckLoginStatus 훅을 mock으로 만들어 localStorage 기반으로 구현
  3. <AuthGuard>로 보호 페이지를 감싸고, 미로그인 시 자동 리다이렉트 동작 확인
  4. 같은 동작을 HOC 버전(withAuthGuard)으로도 만들어 둘의 차이(JSX에서 드러남 vs 감춰짐) 체감

액션 3: 추상화 되돌려 보기 (역방향 연습)

반대로, 지나치게 추상화된 남의 코드를 하나 골라 인라인으로 풀어본다. 풀었을 때 오히려 읽기 쉬워진다면, 추상화가 잘못됐다는 증거다.

확인 포인트

  • 같은 기능을 Wrapper와 HOC 두 방식으로 구현할 수 있다
  • 추상화 전후로 “읽는 사람이 몇 개 맥락을 들어야 하는지” 비교할 수 있다
  • ”이건 추상화하지 말아야 한다”고 말할 수 있는 사례를 1개 갖고 있다

더 깊이 알고 싶다면

관련 노트

  • [[Code Quality MOC]]
  • [[같이 실행되지 않는 코드 분리하기]]
  • [[책임을 하나씩 관리하기]]
  • [[Props Drilling 지우기]]