안녕하세요

클래스 리팩토링 전 본문

우테코 프리코스/3주차

클래스 리팩토링 전

sakuraop 2022. 11. 13. 23:46
class Customer {
    constructor() {
        // 구매 수량
    }

    getPurchaseAmount(money) {
        if (this.checkMoneyValidation(money)) {
            return money / 1000;
        }
    }
    checkMoneyValidation(money) {
        if (money % 1000 === 0 && money !== 0) {
            return true;
        }
        throw new Error("[ERROR] 1,000원으로 나누어 떨어지는 수를 입력해야합니다.");
    }
}

module.exports = Customer;
ㄴ1000원으로 나누어 떨어지는 수 반환
class Generator {
    constructor() {
        // 랜덤한 로또를 담은 배열
    }

    getLottos(amount) {
        return this.makeRandomLotto(amount);
    }

    makeRandomLotto(amount) {
        const sixNumber = [];
        for (let i = 0; i < amount; i++) {
            sixNumber.push(Random.pickUniqueNumbersInRange(1, 45, 6).sort((a, b) => a - b));
        }
        return sixNumber;
    }
}
ㄴ랜덤한 로또 배열 생성
class Printer {
    // 메시지 출력
    constructor() {}

    static lottoResult(winnings) {
        for (let i = 0; i < winnings.length; i++) {
            Console.print(MESSAGE.WINNING[`${i}`] + winnings[i] + MESSAGE.KOREAN_AMOUNT_WORD);
        }
    }

    static printLottos(lottos) {
        lottos.forEach((lotto) => {
            Console.print(lotto);
        });
    }
}
ㄴ복잡한 출력 전용
class Validation {
    static checkNumbersLength(numbers) {
        if (numbers.split(",").length !== 6) {
            throw new Error("[ERROR] 보너스 번호는 6개여야 합니다.");
        }
    }
    static checkBonusLength(number) {
        if (number.toString().length !== 1) {
            throw new Error("[ERROR] 보너스 번호는 1개여야 합니다.");
        }
    }

    static checkRange(numbers) {
        const numberArray = numbers.split(",");
        numberArray.forEach((number) => {
            if (parseInt(number) < 1 || parseInt(number) > 45) {
                throw new Error("[ERROR] 보너스 번호는 1에서 45사이의 숫자여야 합니다.");
            }
        });
    }

    static checkInteger(numbers) {
        const numberArray = numbers.split(",");
        numberArray.forEach((number) => {
            if (!Number.isInteger(parseInt(number))) {
                throw new Error("[ERROR] 숫자를 입력해야 합니다.");
            }
        });
    }

    static checkBonusDuplicate(numbers, bonusNumber) {
        const numbersArray = numbers.split(",");
        if (numbersArray.includes(bonusNumber.toString())) {
            throw new Error("[ERROR] 중복된 숫자가 포함되어 있으면 안됩니다.");
        }
    }

    static checkNumbersDuplicate(numbers) {
        const setNumbers = new Set(numbers.split(","));
        if (numbers.split(",").length !== setNumbers.size) {
            throw new Error("[ERROR] 중복된 숫자가 포함되어 있으면 안됩니다.");
        }
    }
}
ㄴ입력 유효성 검사
class LottoBonus {
    number;

    constructor(bonusNumber) {
        this.validate(bonusNumber);
        this.number = bonusNumber;
    }

    validate(bonusNumber) {
        Validation.checkBonusLength(bonusNumber);
        Validation.checkRange(bonusNumber);
        Validation.checkInteger(bonusNumber);
    }
}
ㄴ입력 유효성 검사
class Lotto {
    #numbers;

    constructor(numbers, bonusNumber) {
        // 입력받은 번호 유효성 검사
        this.printer = new Printer();
        this.amount = new Customer();
        this.lottos = new Generator();
        this.bonus = new LottoBonus(bonusNumber);
        this.resultArray = [];
        this.revenue;
        this.validate(numbers);
        this.#numbers = numbers;
    }

    validate(numbers) {
        Validation.checkInteger(numbers);
        Validation.checkNumbersLength(numbers);
        Validation.checkRange(numbers);
        Validation.checkNumbersDuplicate(numbers);
        Validation.checkBonusDuplicate(numbers, this.bonus.number);
    }

    setAmount() {
        Console.readLine(MESSAGE.PURCHASE, (money) => {
            this.amount = this.amount.getPurchaseAmount(money);
            this.setLottos();
        });
    }

    setLottos() {
        Console.readLine(this.amount + MESSAGE.PURCHASE_RESULT, (money) => {
            this.lottos = this.lottos.getLottos(this.amount);
            this.lottos.forEach((lotto) => {
                Console.print(lotto);
            });
            this.getWinningCount();
        });
    }

    // printLottos(lottos) {
    //     this.lottos.forEach((lotto) => {
    //         Console.print(lotto);
    //     });
    // }

    getWinningCount() {
        const winningCount = [];
        let BONUS_CHANCE = 10;
        const numbersArray = this.#numbers.split(",");
        numbersArray.push(this.bonus.number);

        console.log(this.lottos);

        for (let i = 0; i < this.lottos.length; i++) {
            let count = 0;
            for (let j = 0; j < numbersArray.length; j++) {
                if (this.lottos[i].includes(parseInt(numbersArray[j])) && j < numbersArray.length - 1) {
                    count++;
                }
                if (count == 5 && j == numbersArray.length - 1) {
                    count += BONUS_CHANCE;
                }
            }
            winningCount.push(count);
        }
        console.log(winningCount);
        this.setResultArray(winningCount);
    }

    setResultArray(winningCount) {
        for (let i = 0; i < 5; i++) {
            this.resultArray.push(winningCount.filter((el) => el == i + 3).length);
        }
        this.resultArray[4] += winningCount.filter((el) => el > 10).length;
        [this.resultArray[3], this.resultArray[4]] = [this.resultArray[4], this.resultArray[3]];

        console.log(this.resultArray);
        Printer.lottoResult(this.resultArray);
        this.setRevenue(this.resultArray);
    }

    setRevenue(resultArray) {
        const sum = (resultArray) => {
            let sum = 0;
            for (let i = 0; i < 5; i++) {
                sum += UNIT[i] * resultArray[i];
            }
            return MESSAGE.YIELD + ((sum / this.amount / UNIT.PRICE) * 100).toFixed(1) + "%" + MESSAGE.KOREAN_ENDING_WORD;
        };
        console.log(sum(this.resultArray));
    }
}
ㄴ로또 일치 결과