적절한 함수명과 단일 책임으로 코드 개선하기

TIL

이 글에서는 자바스크립트로 구현된 보드게임의 로직을 개선하는 과정을 다루며,

개선 과정은 함수명 개선 → 중복 제거 → 책임 분리의 단계로 이루어져 있다.

작동하지만 개선이 필요한 코드

주어진 코드는 기능적으로는 문제없이 동작했지만, 더 나은 방식을 고민하다 보니 여러 개선점을 찾을 수 있었다.

function checkLadder(position) {
  switch (position) {
    case 4: return 14;
    case 8: return 30;
    case 21: return 42;
    // ...
    default: return null;
  }
}

function checkSnake(position) {
  switch (position) {
    case 32: return 10;
    case 36: return 6;
    case 48: return 26;
    // ...
    default: return null;
  }
}

 

개선 1. 함수명으로 의도를 명확히 하기

가장 먼저 생각한 부분은 함수명이 모호하다는 것이다.

 

checkLadder, checkSnake는 해당하는 위치의 칸을 판별하고 규칙에 따라 특정 값을 반환하는 함수들인데, 이름만 봐서는 이 함수가 boolean을 반환할지, 숫자를 반환할지 예상하기 어려웠다.

 

그래서 함수가 하는 일을 구체적으로 표현하기 위해 동사 + 명사 조합인 getLadderDestination, getSnakeDestination으로 변경했다.

function getLadderDestination(position) {
  switch (position) {
    // ...
  }
}

function getSnakeDestination(position) {
  switch (position) {
  // ...
  }
}

이제는 이름만 봐도 각각의 함수가 목적지를 반환한다는 것을 알 수 있다.

 

개선 2. 중복 코드 제거하기

함수명을 개선하고 나니 코드의 구조적인 문제가 눈에 들어왔다. 두 함수가 데이터만 다를 뿐 동일한 패턴을 반복하고 있다는 생각이 들었다.

현재 구조의 문제점

  • 동일한 switch 패턴이 반복됨
  • 새로운 특수 칸을 추가할 때마다 비슷한 함수를 또 만들어야 함
  • 게임 규칙이 바뀔 때 여러 곳을 수정해야 함

 

그래서 반복되는 로직과 다뤄야 하는 데이터를 분리하기로 했다.

const GAME_DATA = {
  ladders: { 4: 14, 8: 30, 21: 42, 28: 76, 50: 67, 71: 92, 80: 99 },
  snakes: { 32: 10, 36: 6, 48: 26, 62: 18, 88: 24, 95: 56, 97: 78 }
};

function getSpecialDestination(position, destinationMap) {
  return destinationMap[position] || null;
}
// 사용 예
getSpecialDestination(32, GAME_DATA.snakes); // 10
getSpecialDestination(1, GAME_DATA.ladders); // null

getSpecialDestination라는 하나의 함수를 통해 switch문을 여러 번 쓸 필요가 없어졌고, 게임의 규칙이 변경되거나 새로운 특수 칸이 추가될 경우 GAME_DATA만 수정하면 되니 코드가 더 깔끔해지고 확장성 측면에서도 좋아졌다.

 

개선 3. 책임을 명확히 분리하기

함수명과 중복 코드를 수정하고 나니 또 다른 개선점이 눈에 띄었다. getSpecialDestination 함수가 너무 많은 일을 하고 있었고, 그렇기 때문에 함수명을 정하기가 애매모호했다는 생각이 들었다.

현재 함수의 역할

  • destinationMap에서 해당 position의 값을 조회하고
  • 값이 없을 경우 null을 반환한다

 

많은 개발자들이 좋은 코드를 논할 때 함수는 단일 책임의 원칙을 가져야 한다고 하는데, 이 사실을 머리로는 알면서도 막상 로직을 구현할 때 적용하는 것은 쉽지 않은 것 같다.

 

뭔가 모호하고 여러 일을 하는 것처럼 보이는 이 함수를 다음과 같이 각각의 책임으로 분리했다.

// 단순 값 조회만 담당
function getValueFromMap(position, map) {
  return map[position];
}

// 특수 위치 존재 여부만 판단
function isSpecialPosition(position, map) {
  return getValueFromMap(position, map) !== undefined;
}

// 목적지 반환만 담당
function getDestination(position, map) {
  return getValueFromMap(position, map);
}

이제 각 함수는 명확한 하나의 책임만 가지게 되었다.

 

// 사용 예
function movePlayer(current, dice) {
  const next = current + dice;

  // 사다리 위치라면 해당 목적지로 이동
  if (isSpecialPosition(next, GAME_DATA.ladders)) {
    return getDestination(next, GAME_DATA.ladders);
  }

  // 뱀 위치라면 해당 목적지로 이동
  if (isSpecialPosition(next, GAME_DATA.snakes)) {
    return getDestination(next, GAME_DATA.snakes);
  }

  return next;
}

코드가 더 길어 보이지만 각 함수의 역할이 명확해져서 읽기 쉽고 유지보수하기 좋은 구조가 되었다.

'TIL' 카테고리의 다른 글

Node.js와 Express.js를 이용한 서버 구축  (0) 2025.11.10
상태 관리 설계  (0) 2025.11.10
컴포넌트와 모듈 시스템  (0) 2025.11.10
JavaScript의 this와 MPA 구현  (0) 2025.11.10
innterHTML, innerText, textContent의 차이  (0) 2025.11.10
'TIL' 카테고리의 다른 글
  • Node.js와 Express.js를 이용한 서버 구축
  • 상태 관리 설계
  • 컴포넌트와 모듈 시스템
  • JavaScript의 this와 MPA 구현
고견
고견
개발 자국 남기기
  • 고견
    개발자국
    고견
  • 전체
    오늘
    어제
    • 분류 전체보기 (157) N
      • Frontend (29)
        • Next.js (16)
        • JavaScript (7)
      • CS (19) N
        • 자료구조 (9)
        • 알고리즘 (5)
        • 운영체제 (4) N
        • 네트워크 (1) N
      • TIL (93)
      • Dev Log (16)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    트러블 슈팅
    바닐라 자바스크립트
    useState
    C
    CS
    자료구조
    algorithm
    typescript
    ai 감성 일기장
    cs50
    앱 라우터
    react
    인터페이스
    페이지 라우터
    문자열
    Spa
    배열
    함수 타입
    memory
    Pages Router
    타입 좁히기
    제네릭
    generic
    App Router
    javascript
    emotion diary
    클래스
    Next.js
    알고리즘
    Trouble Shooting
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
고견
적절한 함수명과 단일 책임으로 코드 개선하기
상단으로

티스토리툴바