이름 붙이기

  1. 복잡한 조건에 이름 붙이기

    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);
    

위에서 아래로 읽히게 하기

  1. 시점 이동 줄이기 코드를 읽을 때 코드의 위아래를 왔다갔다 하면서 읽거나, 여러 파일이나 함수, 변수를 넘나들면서 읽는 것을 시점 이동이라고 함.

    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.canInvitegetPolicyByRole(user.role)POLICY_SET 순으로 코드를 위아래를 오가며 읽어야 함

    개선해보기

    1. 조건을 펼쳐서 그래도 드러내기

      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;
        }
      }
      
    2. 조건을 한눈에 볼 수 있는 객체로 만들기

      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>
        );
      }
      
  2. 삼항 연산자 단순하게 하기

    삼항 연산자를 복잡하게 사용하면 조건의 구조가 명확하게 보이지 않아서 코드를 읽기 어려울 수 있음.

    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";
    })();