더러운 코드를 고쳐보자

기존코드

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

클린코드에서 배운 내용을 토대로 고친 코드

  • 구현 소스코드
function runChristmasClockEverySecond(){
    setInterval(setChristmasRemainingClockTime, 1000);
}

function setChristmasRemainingClockTime() {
    const christmasClock = new ChristmasClock();
    setChristmasClockElementTimeRemains(christmasClock.getRemainingChristmasTimegap());
}

function setChristmasClockElementTimeRemains({day, hours, minutes, seconds}){
    getChristmasClockElement().innerText = `${day}d ${hours}h ${minutes}m ${seconds}s`;
}

function getChristmasClockElement(){
    return christmasClock = document.querySelector(".js-clock");
}

runChristmasClockEverySecond();
  • ChristmasClock 클래스
class ChristmasClock{

    DAY = 1000 * 60 * 60 * 24;
    HOUR = 1000 * 60 * 60;
    MINUTE = 1000 * 60;
    SECOND = 1000;

    constructor(){
    }

    getTodayChristmasTimegap(){
        return this.getThisYearChristmasDate() - new Date();
    }
    
    getThisYearChristmasDate(){
        let christmasYear = new Date().getFullYear();
        if (this.isThisYearChristmasHasPassed()) {
            christmasYear = christmasYear + 1;
        }
        return new Date(christmasYear, 12, 25);
    }

    isThisYearChristmasHasPassed(){
        let today = new Date();
        if (today.getMonth() == 11 && today.getDate() > 25) {
            return true
        } else {
            return false
        }
    }
    
    getRemainingGapDays(timeGap){
        const remainingDays = Math.floor(timeGap / this.DAY);
        return String(remainingDays).padStart(2, "0");
    }
    
    getRemainingGapHours(timeGap){
        const remainingDays = Math.floor(timeGap / this.DAY); 
        const remainingHours = Math.floor((timeGap - (remainingDays * this.DAY)) / this.HOUR);
        return String(remainingHours).padStart(2, "0");
    }
    
    getRemainingGapMinutes(timeGap){
        const reamainingMinutes = Math.floor((timeGap % this.HOUR) / this.MINUTE);
        return String(reamainingMinutes).padStart(2, "0");
    }
    
    getRemainingGapSeconds(timeGap){
        const remainingSeconds = Math.floor((timeGap % this.MINUTE) / this.SECOND);
        return String(remainingSeconds).padStart(2, "0");
    }

    getRemainingChristmasTimegap(){
        return {
            day: this.getRemainingGapDays(this.getTodayChristmasTimegap()),
            hours: this.getRemainingGapHours(this.getTodayChristmasTimegap()),
            minutes: this.getRemainingGapMinutes(this.getTodayChristmasTimegap()),
            seconds: this.getRemainingGapSeconds(this.getTodayChristmasTimegap())
        }
    }
}

고친 내용들

  • 알기 쉬운 명명규칙으로 변경하였다
  • 너무 긴 함수를 클래스로 추상화하고 묶었으며 짧고 간결하게 변경했다.
  • 전체적으로 소스코드는 길어졌지만 하나의 함수에서 여러 단계의 추상화를 함수단위로 쪼개서 하나의 함수에선 하나의 일만 처리하게끔 변경하였다.