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

이 글에서는 JavaScript로 구현된 보드게임의 로직을 개선하는 과정을 다루며, 개선 과정은 함수명 개선 → 중복 제거 → 책임 분리의 단계로 이루어져있다.
작동하지만 개선이 필요한 코드
처음에 작성한 코드는 기능적으로는 문제없이 동작했지만, 더 나은 방식을 고민하다 보니 여러 개선점을 찾을 수 있었다.
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;
}
Subscribe to my newsletter
Read articles from woodstock directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

woodstock
woodstock
안녕하세요! 프론트엔드 개발자 woodstock입니다. 저는 매일 조금씩 발전하고자 하는 마음으로 개발공부를 시작했고, 이 블로그는 그 과정에서 배우고 성장하는 이야기를 담고 있습니다. 여러분의 피드백과 조언은 언제나 환영합니다! 함께 배우고 성장하는 과정을 즐길 수 있기를 기대합니다.