다잘하고싶어

[프리코스] 3주차 과제_ 로또게임 본문

우테코 프리코스

[프리코스] 3주차 과제_ 로또게임

챙영잉 2022. 11. 14. 15:51

package lotto;

import camp.nextstep.edu.missionutils.Console;

import java.util.Arrays;
import java.util.List;

public class Player {
    public static int money;
    public static int numberOfLottos;
    public static List<Integer> winNumbers;

    public static int getMoney() {
        String playerInput = Console.readLine();
        validateNumbers(playerInput);
        money = Integer.parseInt(playerInput);
        validate(money);
        numberOfLottos = money/1000;
        return money;
    }

    public static List<Integer> getWinNumbers(){
        String playerInput = Console.readLine();
        toMakeWinNumbers(playerInput);
        for (int i = 0; i < winNumbers.size(); i++) {
            validate(winNumbers.get(i));
        }
        return winNumbers;
    }

    private static void toMakeWinNumbers(String playerInput) {
        List<String> beforeCheck = Arrays.asList(playerInput.split(","));
        System.out.println(beforeCheck);
        for (int i = 0; i < beforeCheck.size(); i++) {
            winNumbers.add(Integer.parseInt(beforeCheck.get(i)));
            System.out.println(winNumbers);
        }
    }

    private static void validate(int money) {
        if (money % 1000 != 0) {
            throw new IllegalArgumentException("[ERROR]구입 금액은 1,000원 단위로 나누어 떨어져야 합니다.");
        }
    }

    private static boolean validateNumbers(String playerInput){
        try {
            Integer.parseInt(playerInput);
            return true;
        } catch (Exception ex) {
            throw new IllegalArgumentException("[ERROR]숫자가 아닌 값을 포함하고 있습니다.");
        }
    }

}

현재 상황 : 사용자에게 6개의 숫자를 입력받는 과정에서 NullPointException 발생

34번째 라인의 초기화 과정이 없어서 에러난 것. 

add 하기 전에 바로 널포인트익셉션 난다. 초기화 빼먹지않도록 주의하기.

 


현재상황 : 아래의 요구사항을 지키려다보니, 생성자 Lotto를 외부에서 호출할수가없어서 막혔다.

현재 나의 코드는 

package lotto;

import camp.nextstep.edu.missionutils.Randoms;
import lotto.view.Print;

import java.util.List;

public class Lotto {
    private final List<Integer> numbers;

    public Lotto(List<Integer> numbers) {
        getRandomNumbers(numbers);
        validate(numbers);
        this.numbers = numbers;
        //printLottos(numbers);
    }

    private void validate(List<Integer> numbers) {
        if (numbers.size() != 6) {
            throw new IllegalArgumentException();
        }
    }
    // TODO: 추가 기능 구현

    public static List<Integer> getRandomNumbers(List<Integer> numbers){
        numbers = Randoms.pickUniqueNumbersInRange(1, 45, 6);
        return numbers;
    }


    public static void printLottos(List<Integer> numbers) {
        int times = Player.numberOfLottos;
        for (int i = 0; i < times; i++) {
            Print.getLottos(numbers);
        }
    }
}

 

 

그래서 랜덤숫자 생성하는 메서드를 클래스로 따로 빼기로 했다. 

 

 

[소감]

안녕하세요. 이번 주는 어느 때보다 열정적이었고 그만큼 힘들었던 미션 주간을 보낸 것 같습니다.
다시 돌이켜보면 네 번의 큰 산을 만났던 것 같습니다.
미션 초반 가장 어려웠던 점은 추가적인 요구사항을 지키려고 노력하느라, 기능 구현의 속도가 너무 더디다는 것이었습니다. 인덴스 제약조건을 지키고, 클래스와 메서드를 최대한 작게 만드는 데 집중하다보니, 정작 메인 기능 구현이 더 복잡하게 느껴지기까지 했습니다. 그래서 일단 다른 제약조건들은 제쳐두고, 로또 게임 자체를 프로그래밍 하는 데 집중했습니다. 그 과정에서 작성한 코드가 부끄럽게 느껴져서 커밋을 하는 것이 망설여졌지만, 배움의 과정이라 생각하고 기록을 남겼습니다. 
두 번째는 주어진 로또클래스를 외부에서 호출하는 과정에서, private 변수들을 어떻게 사용할 지에 대한 고민이었습니다. getter 사용을 최대한 지양하라는 것과, 기본생성자를 추가하지말라는 조건 안에서 많은 고민을 하다가, 결국 필요한 로직 구현을 로또 클래스 안에서 마치고, 그 결과값들을 외부에서 호출해서 사용하도록 구현했습니다. 이해하기 쉽고 합리적인 코드인가에 대한 고민은 여전히 있는 것 같습니다.
세 번째는 예외처리에 대한 요구사항이었습니다. 이전 야구게임과 마찬가지로 구현하면 될 것이라고 생각했지만, 요구사항을 꼼꼼히 읽어보니, "예외를 발생시키고 메세지 출력 후 종료"라는 조건이었습니다. 예외 발생 시 자동으로 종료되는 상황을 어떻게 해결할 것인가에 대한 고민이 계속되었습니다. 결국 throw 를 사용하여 메인클래스까지 예외를 넘기고, 메세지 출력 후 return 을 통해 종료하는 방식으로 구현하였습니다. 예외처리에 대한 공부가 더 필요함을 느꼈습니다.
마지막으로는 중복체크 테스트코드 미통과 문제였습니다. 정리해보면 사용자 입력 값 역시 Lotto클래스에 넣어야 하기에 Lotto 안에서도 중복체크를 해줘야하는데, 사용자 입력 시에만 중복체크를 했기 때문에 고정된 테스트 코드를 통과하지 못했던 것이었습니다. 간단한 문제였는데, 기본적인 것을 놓치고 어렵게만 생각해서 꽤 오랜 시간을 투자해야했던 문제였습니다. 
이번 미션에는 TDD 방식을 적극적으로 도입해보고 싶었지만, 현재 저의 상황에서는 메인 기능 구현에 먼저 집중해야 한다고 생각했습니다. 더 많은 시간을 들여 테스트 코드를 작성해보고 공부하며 다음 미션에서는 꼭 TDD 방식의 장점을 직접 느껴보고 싶습니다.