FEInterview Prep

토스 · SLASH 21 2021

실무에서 바로 쓰는 Frontend Clean Code

유지보수 시간을 줄이는 응집도·단일책임·추상화 실전 사례 (발표: 진유림)

클린 코드리팩토링응집도단일 책임

요약

핵심 토픽

클린 코드응집도단일 책임 원칙추상화선언적 프로그래밍

학습 포인트

1. 응집도: 같은 목적의 코드는 모아라

관련 코드(상태, 이벤트 핸들러, 컴포넌트)가 여러 파일에 흩어지면 기능 수정 시 파일을 넘나들어야 합니다. 커스텀 훅으로 관련 로직을 묶되, '당장 몰라도 되는 구현 디테일'만 숨기고 '코드 파악에 필수적인 핵심 정보(팝업 제목, 버튼 액션)'는 밖에 드러내야 합니다. 잘못된 응집: `usePopupLogic()`이 제목·액션까지 내부에 숨겨버리면 사용 측에서 팝업이 어떤 내용인지 파악 불가. 올바른 응집: `usePopup({ title, onConfirm })`처럼 핵심 정보를 인수로 받으면 됩니다.

핵심 용어

응집도커스텀 훅선언적 프로그래밍관심사 분리정보 은닉

2. 단일 책임 원칙(SRP): 함수는 하나의 일만

함수 이름이 약속하는 것과 실제 동작이 일치해야 합니다. `handleSubmit`이 API 호출 외에 약관 동의 검사·로깅·리다이렉트까지 한다면, 함수 이름을 믿을 수 없게 됩니다. 하나의 명확한 책임을 가진 함수로 분리(`checkAgreement`, `submitForm`, `logEvent`)하면 각 함수를 독립적으로 테스트하고 재사용할 수 있습니다. 판단 기준: 함수를 설명할 때 'A를 하고, B도 한다'고 말하게 되면 분리 시그널입니다.

핵심 용어

단일 책임 원칙SRP함수 분리이벤트 핸들러 네이밍테스트 용이성

3. 추상화: 핵심 개념만 드러내라

피카소의 소 스케치처럼, 코드도 단계적으로 불필요한 디테일을 제거하고 핵심 개념만 남겨야 합니다. 추상화 수준을 일관되게 유지하는 것이 중요합니다. 예: 함수 내에서 'HTTP 요청 헤더 설정'(저수준)과 '회원 정보 조회'(고수준)가 섞이면 코드 파악이 어렵습니다. 컴포넌트의 JSX도 마찬가지로, 버튼 하나에 onClick 로직 20줄이 인라인으로 있으면 구조 파악이 어렵습니다. `<SubmitButton onClick={handleSubmit}/>`처럼 추상화된 이름을 쓰면 읽기 쉬워집니다.

핵심 용어

추상화추상화 레벨선언적 API컴포넌트 합성가독성

4. 기능 추가 시 클린 코드 유지하기

코드를 잘 모르는 상태에서 기능을 추가하면 기존 원칙이 무너집니다. 발표자가 강조하는 방법: 기능 추가 전 파일 전체를 다시 읽고 전체 맥락을 파악하세요. PR 크기를 작게 유지하되, 리팩토링 PR과 기능 추가 PR을 분리하면 리뷰어가 의도를 명확히 파악할 수 있습니다. '돌아가는 코드'에서 '유지보수 가능한 코드'로 전환하는 것은 일회성이 아니라 매 PR마다 적용해야 하는 습관입니다.

핵심 용어

기능 추가 전 코드 읽기리팩토링 PR 분리코드 리뷰PR 크기 관리기술 부채

면접 질문

초급

Q1. 좋은 함수 이름을 짓는 기준은 무엇이고, 나쁜 예시를 어떻게 리팩토링하나요?

힌트

[감점 답변] 정의만 반복하거나 "좋은 함수 이름을 짓는 기준은 무엇이고, 나쁜 예시를 어떻게 리팩토링하나요?"에 대해 장단점 없이 단편적으로 답하면 감점 포인트입니다. 면접관은 실무 적용 경험이 부족하다고 판단합니다. [좋은 답변] 함수명과 동작의 일치, 동사+명사 구조, 단일 책임으로 설명하세요. 나쁜 예: `handleClick`(무엇을 클릭?), `processData`(무슨 처리?) → 좋은 예: `submitPaymentForm`, `fetchUserProfile`. 추가로 '함수를 설명할 때 and로 두 가지를 연결하게 되면 분리 신호'라는 실용적 판단 기준을 언급하면 답변이 더욱 풍부해집니다.

중급

Q2. 커스텀 훅으로 로직을 추상화할 때 오히려 가독성이 나빠지는 경우는 어떤 때인가요?

힌트

[감점 답변] 정의만 반복하거나 "커스텀 훅으로 로직을 추상화할 때 오히려 가독성이 나빠지는 경우는 어떤 때인가요?"에 대해 장단점 없이 단편적으로 답하면 감점 포인트입니다. 면접관은 실무 적용 경험이 부족하다고 판단합니다. [좋은 답변] 핵심 정보(팝업의 제목, 확인 버튼 동작)까지 훅 내부에 숨겨버려 사용 측에서 훅만 봐서는 어떤 동작인지 파악할 수 없는 경우를 설명하세요. 해결책: 핵심 의사결정은 사용 측에서 props로 전달하고, 공통 로직(열기/닫기 상태 관리)만 훅이 담당하도록 경계를 설정해야 합니다.

중급

Q3. 단일 책임 원칙(SRP)을 컴포넌트 분리에 적용하는 기준을 설명해 주세요.

힌트

[감점 답변] 정의만 반복하거나 "단일 책임 원칙(SRP)을 컴포넌트 분리에 적용하는 기준을 설명해 주세요."에 대해 장단점 없이 단편적으로 답하면 감점 포인트입니다. 면접관은 실무 적용 경험이 부족하다고 판단합니다. [좋은 답변] 컴포넌트를 분리할 때의 판단 기준을 설명하세요: (1) 컴포넌트를 한 문장으로 설명하기 어려우면 분리 신호, (2) props 수가 5개 이상이면 복잡성 검토 필요, (3) 재사용 가능한 부분과 특정 맥락에 종속된 부분의 경계가 명확한지 확인. 컴포넌트 분리가 오버엔지니어링이 되는 경우(단 한 곳에서만 쓰이는 작은 컴포넌트 분리)도 함께 언급하면 균형 있는 답변이 됩니다.

중급

Q4. 레거시 코드에 기능을 추가할 때 클린 코드를 유지하는 방법은 무엇인가요?

힌트

[감점 답변] 정의만 반복하거나 "레거시 코드에 기능을 추가할 때 클린 코드를 유지하는 방법은 무엇인가요?"에 대해 장단점 없이 단편적으로 답하면 감점 포인트입니다. 면접관은 실무 적용 경험이 부족하다고 판단합니다. [좋은 답변] 먼저 파일 전체를 읽고 맥락을 파악하라는 발표 내용을 언급하세요. 그다음 리팩토링과 기능 추가를 같은 PR에 섞지 않는 것, 작은 단위로 개선하는 Boy Scout Rule('코드를 만졌으면 조금 더 깔끔하게'), 그리고 테스트 코드 없는 리팩토링의 위험성도 설명하면 경험 있는 답변이 됩니다.

고급

Q5. 추상화 레벨을 일관되게 유지한다는 것이 무슨 의미인지 코드 예시와 함께 설명해 주세요.

힌트

[감점 답변] 정의만 반복하거나 "추상화 레벨을 일관되게 유지한다는 것이 무슨 의미인지 코드 예시와 함께 설명해 주세요."에 대해 장단점 없이 단편적으로 답하면 감점 포인트입니다. 면접관은 실무 적용 경험이 부족하다고 판단합니다. [좋은 답변] 같은 함수 안에 고수준 비즈니스 로직과 저수준 구현 디테일이 섞인 예시를 들어 설명하세요. 예: 결제 처리 함수에서 'HTTP 헤더 설정'(저수준)과 '주문 완료 처리'(고수준)가 섞여있는 케이스. 저수준 코드를 별도 함수로 분리해 호출 측의 추상화 레벨을 통일하면 각 함수가 하나의 추상화 레벨만 다루게 된다는 점을 구체적으로 설명하면 됩니다.

선행 학습

  • React 컴포넌트 기초와 커스텀 훅
  • JavaScript 함수 설계 기본
  • 기본적인 리팩토링 경험

핵심 타임스탬프

클린 코드 핵심 구간00:00 - 03:00
응집도 핵심 구간03:00 - 07:00
단일 책임 원칙 핵심 구간07:00 - 12:00
추상화 핵심 구간12:00 - 17:00

학습 방법

1단계: 본인이 작성한 기존 컴포넌트 중 가장 복잡한 것을 골라 응집도·단일책임·추상화 세 기준으로 어떤 문제가 있는지 분석해보세요. 2단계: 분석 결과를 바탕으로 리팩토링 PR을 만들되, 기능 추가 없이 구조만 개선하는 PR을 완성하세요. 이 과정에서 '어디서 자르고 어디는 같이 묶을지'를 결정하는 판단력이 생깁니다. 3단계: 팀 코드 리뷰에서 다른 사람의 코드에도 동일한 기준을 적용해 피드백해보면 개념이 더 빠르게 내재화됩니다. 4단계: 동료에게 "클린 코드"의 핵심을 5분 안에 설명해보세요. 막히는 부분이 아직 구조적으로 이해되지 않은 지점입니다.