6-1. 함수 추출하기

적용 시점

  • 코드 조각을 찾아 무슨 일을 하는지 파악한 다음, 독립된 함수로 추출하고 목적에 맞는 이름을 붙인다.

  • 너무 길어진 코드나 두 번 이상 사용되는 부분은 역할을 분리하여 함수로 만든다.

절차

  1. 함수를 새로 만들고 목적을 잘 드러내는 이름을 붙임

  2. 추출할 코드를 원본 함수에서 복사하여 새 함수에 붙임

  3. 추출한 코드 중 원본 함수의 지역 변수를 참조하거나 추출한 함수의 유효범위를 벗어나는 변수는 없는지 검사하고, 있다면 매개변수로 전달

  4. 변수를 다 처리했다면 컴파일

  5. 원본 함수에서 추출한 코드 부분을 새로 만든 함수를 호출하는 문장으로 바꿈

  6. 테스트 함

  7. 다른 코드에 방금 추출한 것과 똑같거나 비슷한 코드가 없는지 살피고 있다면 방금 추출한 새 함수를 호출하도록 바꿀지 검토

예시

❌ Before

export const getCalendarInfo = ({
  year,
  month,
  futureDate,
  pastDate,
  selectedButtonOrder,
}: {
  year: number;
  month: number;
  futureDate: string;
  pastDate: string;
  selectedButtonOrder: number;
}) => {
  const firstDay = new Date(year, month - 1, 1).getDay();
  const lastDate = new Date(year, month, 0).getDate();
  const data: { available: boolean; date: string | number; backgroundPoint: boolean }[][] = [];
  let nowDate = 1;
  let nowDay = 0;
  let weekIdx = 0;
  while (nowDate <= lastDate) {
    if (nowDay === 0) {
      data.push([]);
    }
    if (weekIdx === 0) {
      if (nowDay < firstDay) {
        data[weekIdx].push({ available: false, date: '', backgroundPoint: false });
        nowDay += 1;
        continue;
      }
    }

    const nowDateToTime = new Date(`${year}-${month < 10 ? 0 : ''}${month}-${nowDate < 10 ? '0' : ''}${nowDate}`).getTime();
    const pastDateToTime = new Date(pastDate).getTime();
    const futureDateToTime = new Date(futureDate).getTime();
    const dueDateToTime = new Date().getTime();
    data[weekIdx].push({
      available: getClickAvailable({ selectedButtonOrder, dueDateToTime, nowDateToTime }),
      date: nowDate,
      backgroundPoint: pastDateToTime <= nowDateToTime && nowDateToTime <= futureDateToTime,
    });

    nowDate += 1;
    nowDay += 1;
    if (nowDay === 7) {
      nowDay = 0;
      weekIdx += 1;
    }
  }
  return data;
};

⭕ After

export const changeFormCalendarNumber = (cur: number) => `${cur < 10 ? 0 : ''}${cur}`;

const getDateToTime = ({
  year,
  month,
  nowDate,
  pastDate,
  futureDate,
}: {
  year: number;
  month: number;
  nowDate: number;
  pastDate: string;
  futureDate: string;
}) => {
  const nowDateToTime = new Date(`${year}-${changeFormCalendarNumber(month)}-${changeFormCalendarNumber(nowDate)}`).getTime();
  const pastDateToTime = new Date(pastDate).getTime();
  const futureDateToTime = new Date(futureDate).getTime();
  const dueDateToTime = new Date().getTime();
  return { nowDateToTime, pastDateToTime, futureDateToTime, dueDateToTime };
};

export const getCalendarInfo = ({
  year,
  month,
  futureDate,
  pastDate,
  selectedButtonOrder,
}: {
  year: number;
  month: number;
  futureDate: string;
  pastDate: string;
  selectedButtonOrder: number;
}) => {
  const firstDay = new Date(year, month - 1, 1).getDay();
  const lastDate = new Date(year, month, 0).getDate();
  const data: { available: boolean; date: string | number; backgroundPoint: boolean }[][] = [];
  
	let nowDate = 1;
  let nowDay = 0;
  let weekIdx = 0;

  while (nowDate <= lastDate) {
    if (nowDay === 0) {
      data.push([]);
    }
    if (weekIdx === 0) {
      if (nowDay < firstDay) {
        data[weekIdx].push({ available: false, date: '', backgroundPoint: false });
        nowDay += 1;
        continue;
      }
    }

    const { dueDateToTime, futureDateToTime, nowDateToTime, pastDateToTime } = getDateToTime({ year, month, nowDate, pastDate, futureDate });

    data[weekIdx].push({
      available: getClickAvailable({ selectedButtonOrder, dueDateToTime, nowDateToTime }),
      date: nowDate,
      backgroundPoint: pastDateToTime <= nowDateToTime && nowDateToTime <= futureDateToTime,
    });

    nowDate += 1;
    nowDay += 1;
    if (nowDay === 7) {
      nowDay = 0;
      weekIdx += 1;
    }
  }
  return data;
};

Last updated