복잡한 조건에 이름 붙이기
조건식에 이름을 붙이는 것이 좋을 때
복잡한 로직을 다룰 때
재사용성이 필요할 때
단위 테스트가 필요할 때
함수를 분리하면 독립적으로 단위 테스트를 작성할 수 있다. 단위 테스트는 함수가 올바르게 동작하는지 쉽게 확인할 수 있어, 복잡한 로직을 테스트 할 때 특히 유용하다.
조건에 이름을 붙이지 않아도 괜찮을 때
로직이 간단할 때
예를 들어, 배열의 요소를 단순히 두 배로 만드는 arr.map(x => x * 2)
와 같은 코드는 이름을 붙이지 않아도 직관적이에요.
한 번만 사용될 때
사람의 뇌가 한 번에 저장할 수 있는 정보의 숫자는 6개임 (by. 프로그래머의 뇌)
b. 매직 넘버에 이름 붙이기
매직 넘버(Magic Number)란 정확한 뜻을 밝히지 않고 소스 코드 안에 직접 숫자 값을 넣는 것
코드 예시
async function onLikeClick() {
await postLike(url);
await delay(300);
await refetchPostLike();
}
이 코드는 delay
함수에 전달된 300
이라고 하는 값이 어떤 맥락으로 쓰였는지 알 수 없음. 원래 코드를 작성한 개발자가 아니라면, 어떤 목적으로 300ms동안 기다리는지 알 수 없음.
개선해보기
숫자 300
의 맥락을 정확하게 표시하기 위해서 상수 ANIMATION_DELAY_MS
로 선언할 수 있음
await delay(ANIMATION_DELAY_MS);
시점 이동 줄이기 코드를 읽을 때 코드의 위아래를 왔다갔다 하면서 읽거나, 여러 파일이나 함수, 변수를 넘나들면서 읽는 것을 시점 이동이라고 함.
function Page() {
const user = useUser();
const policy = getPolicyByRole(user.role);
return (
<div>
<Button disabled={!policy.canInvite}>Invite</Button>
<Button disabled={!policy.canView}>View</Button>
</div>
);
}
function getPolicyByRole(role) {
const policy = POLICY_SET[role];
return {
canInvite: policy.includes("invite"),
canView: policy.includes("view")
};
}
const POLICY_SET = {
admin: ["invite", "view"],
viewer: ["view"]
};
위 코드는 policy.canInvite
→ getPolicyByRole(user.role)
→ POLICY_SET
순으로 코드를 위아래를 오가며 읽어야 함
개선해보기
조건을 펼쳐서 그래도 드러내기
function Page() {
const user = useUser();
switch (user.role) {
case "admin":
return (
<div>
<Button disabled={false}>Invite</Button>
<Button disabled={false}>View</Button>
</div>
);
case "viewer":
return (
<div>
<Button disabled={true}>Invite</Button>
<Button disabled={false}>View</Button>
</div>
);
default:
return null;
}
}
조건을 한눈에 볼 수 있는 객체로 만들기
function Page() {
const user = useUser();
const policy = {
admin: { canInvite: true, canView: true },
viewer: { canInvite: false, canView: true }
}[user.role];
return (
<div>
<Button disabled={!policy.canInvite}>Invite</Button>
<Button disabled={!policy.canView}>View</Button>
</div>
);
}
삼항 연산자 단순하게 하기
삼항 연산자를 복잡하게 사용하면 조건의 구조가 명확하게 보이지 않아서 코드를 읽기 어려울 수 있음.
const status =
(A조건 && B조건) ? "BOTH" : (A조건 || B조건) ? (A조건 ? "A" : "B") : "NONE";
개선해보기
다음과 같이 조건을 if
문으로 풀어서 사용하면 보다 명확하고 간단하게 조건을 드러낼 수 있음. (early return)
const status = (() => {
if (A조건 && B조건) return "BOTH";
if (A조건) return "A";
if (B조건) return "B";
return "NONE";
})();