미션! 더러운 코드를 고쳐라!
const merry = document.querySelector(".js-clock");
function getClock() {
const christmas = new Date("2021, 12, 25");
const date = new Date();
const timeGap = christmas - date;
const xDay = Math.floor(timeGap / (1000 * 60 * 60 * 24));
const xHours = Math.floor(
(timeGap - xDay * 1000 * 60 * 60 * 24) / (1000 * 60 * 60)
);
const xMinutes = Math.floor((timeGap % (60 * 60 * 1000)) / (60 * 1000));
const xSeconds = Math.floor((timeGap % (60 * 1000)) / 1000);
const day = String(xDay).padStart(2, "0");
const hours = String(xHours).padStart(2, "0");
const minutes = String(xMinutes).padStart(2, "0");
const seconds = String(xSeconds).padStart(2, "0");
merry.innerText = `${day}d ${hours}h ${minutes}m ${seconds}s`;
}
getClock();
setInterval(getClock, 1000);
고친 코드
const $dDayClock = document.querySelector(".js-clock");
const printTimeLeftUntilChristmas = () => {
const datePhrase = getDatePhraseOfTimeLeftUntilChristmas();
$dDayClock.textContent = datePhrase;
};
const getDatePhraseOfTimeLeftUntilChristmas = () => {
const currentDate = new Date();
const christmasDate = getNextChristmasDateFrom(currentDate);
return getDatePhraseOfTimeGapFromDateUntilDate(currentDate, christmasDate);
};
const getNextChristmasDateFrom = (currentDate) => {
const currentYear = currentDate.getFullYear();
return new Date(`${currentYear}, 12, 25`);
};
const getDatePhraseOfTimeGapFromDateUntilDate = (fromDate, untilDate) => {
const timeGapUntilChristmas = getMillisecondsFromDateUntilDate(
fromDate,
untilDate
);
const rawDateObjectOfTimeGap = convertMillisecondsToDateObject(
timeGapUntilChristmas
);
const { days, hours, minutes, seconds } = getDateObjectMatchedDigits(
rawDateObjectOfTimeGap
);
return `${days}일 ${hours}시 ${minutes}분 ${seconds}초`;
};
const getMillisecondsFromDateUntilDate = (fromDate, untilDate) => {
return untilDate - fromDate;
};
const convertMillisecondsToDateObject = (milliseconds) => {
const date = {};
const oneSecond = 1000;
const oneMinute = oneSecond * 60;
const oneHour = oneMinute * 60;
const oneDay = oneHour * 24;
const remainderAfterDivisionBy = {
days: milliseconds % oneDay,
hours: milliseconds % oneHour,
minutes: milliseconds % oneMinute,
};
date.days = Math.floor(milliseconds / oneDay);
date.hours = Math.floor(remainderAfterDivisionBy.days / oneHour);
date.minutes = Math.floor(remainderAfterDivisionBy.hours / oneMinute);
date.seconds = Math.floor(remainderAfterDivisionBy.minutes / oneSecond);
return date;
};
const getDateObjectMatchedDigits = (rawDateObject) => {
const date = {};
for (const [key, value] of Object.entries(rawDateObject)) {
key === "days"
? (date[key] = pad0ForMatchingDigit(value, 3))
: (date[key] = pad0ForMatchingDigit(value, 2));
}
return date;
};
const pad0ForMatchingDigit = (number, digit) => {
return String(number).padStart(digit, "0");
};
const init = () => {
printTimeLeftUntilChristmas();
setInterval(printTimeLeftUntilChristmas, 1000);
};
init();
🧐 리팩토링 포인트
- 기능 별로 여러 개의 함수로 쪼갰다.
- 확장성을 높이기 위해 보편적으로 사용 가능한 부분과 특정 상황에서만 사용 가능한 부분을 분리해 각각 함수로 만들었다.
- 코드의 의미 파악을 돕기 위해 수식과 상수에 변수명을 붙였다.
- 중복되는 작업을 for문으로 처리하기 위해 자료 구조를 객체로 반환했다.
📌 소감 3줄 요약
- 정확한 함수의 의도를 함수명에 담으려고 하니까 함수명이 많이 길어져서 가독성이 더 나아졌는지 헷갈린다.
- 함수를 호출한 순서대로 적는 게 좋을지 지금 코드 독해 맥락에서 가장 중요한 부분부터 적는 게 좋을지 고민이 됐다.
- 인수의 숫자를 줄여보려고 했지만 어쩔 수 없이 쓰게 되는 부분들이 있는데 함수명에서 인수의 존재를 암시해야 하는 부분이 어려웠다.
'클린코드' 카테고리의 다른 글
[DAY 12] 클린 코드 TIL - 7장. 오류 처리 (0) | 2022.02.02 |
---|---|
[DAY 11] 클린 코드 TIL - 6장. 객체와 자료구조 (0) | 2022.02.01 |
[DAY 9] 클린 코드 TIL - 5장. 형식 맞추기 (0) | 2022.01.30 |
[DAY 8] 클린 코드 TIL - 4장. 주석 (0) | 2022.01.29 |
[DAY 7] 클린 코드 TIL - 4장. 주석 (0) | 2022.01.28 |