ETC/2023 우테코 프리코스

[1회차] 1회차 숫자 야구게임 리팩토링

chaerrii 2023. 12. 5. 00:15

미루고 미루던 1회차 숫자 야구 게임 리팩토링을 진행했다. 

예전의 코드는 Application에 그냥 적었었는데, 다시 객체지향(?) 적으로 해보았다.

 

예전 코드

        boolean a =true;
        while (a) {
            List<Integer> computer = new ArrayList<>();
            List<Integer> people = new ArrayList<>();
            int strike = 0;
            int ball = 0;
            while (computer.size() < 3) { //만약 컴퓨터 배열의 크기가 3이상이 아니면,
                int randomNum = Randoms.pickNumberInRange(1, 9); //랜덤 넘버를 뽑는다.
                if (!computer.contains(randomNum)) { //만약 뽑힌 랜덤넘버가 컴퓨터 리스트 안에 없으면,
                    computer.add(randomNum); //랜덤 넘버를 집어넣는다.
                }
            } //3개의 랜덤 넘버를 모두 만든 컴퓨터
            //사용자가 입력한다.
            System.out.println("숫자 야구 게임을 시작합니다.");
            System.out.println("숫자를 입력해주세요: ");
            String num = Console.readLine();
            if(!num.matches("[0-9]+")){
                throw new IllegalArgumentException("숫자만 입력해주세요.");
            }
            for (int i = 0; i < 3 ; i++) {
                char n = num.charAt(i); //num을 문자열 하나하나로 자름
                Integer m = Character.getNumericValue(n); //다시 char을 Int로 만듬
                if(people.contains(m)){
                    throw new IllegalArgumentException("중복되는 값을 입력할 수 없습니다.");
                }
                people.add(m);
            }

            for (int i = 0; i < computer.size(); i++) {
                for (int j = 0; j < people.size(); j++) {
                    if (computer.get(i).equals(people.get(j)) && i == j) {
                        strike++;
                    } else if (computer.get(i).equals(people.get(j)) && i!=j) {
                        ball++;
                    }
                }
             }
            if(strike==3) {
                System.out.println(strike + "스트라이크");
                System.out.println("3개의 숫자를 모두 맞히셨습니다! 게임 종료");
                System.out.println("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요.");
                String n = Console.readLine();
                if(n.equals("2")){
                    a = false;
                } else {
                    continue;
                }
            } else if(strike==0 && ball ==0){
                System.out.println("낫싱");
            } else if(strike==0 && ball>0){
                System.out.println(ball+"볼");
            } else if(strike>0 && ball==0){
                System.out.println(strike + "스트라이크");
            } else{
                System.out.println(strike + "스트라이크" +ball+"볼");
            }
        }
    }

사실 이거를 ㅋㅋ 어 코드라고 해도 되나? 올려도 되나? 싶을 만큼 쪽팔렸다. 왜냐면...나는 미션을 다 죄다 이렇게 제출하라는 줄 알고, 자바의 특성을 1나도 살리지 못한채 제출했기 때문이다. 코드를 짜면서 어 ez 라고 생각했는데 한참 잘못 알고 있었다...그래서 회차가 진행될 수록 1회차는 꼭 리팩토링 해야지라고 생각했었는데, 미루고 미루다가 이제야 하게 되었다.

사실 리팩토링 나름대로 한 것도 잘 한건지도 모르겠지만, 전보다는 나아졌을 거라 믿는다.

구조

원래 Application 하나에 로직을 죄다 때려 박았었지만, 나름대로 MTV를 나눠서 해보았다. 사실 나는 MTV 패턴을 잘 모른다(..) 장고할 때 배운거 밖에?? MTV 패턴이 따로 있는 거 같은데 그냥 아는대로 해봤다.

의문인 점??

이것은 GameService에 있는 putComputerNumbers()이다. 랜덤 넘버를 생성해서 배열로 만드는 메소드이다.

public List<Integer> putComputerNumbers() {
    List<Integer> numbers = new ArrayList<>();
    while (numbers.size() < 3) { //만약 컴퓨터 배열의 크기가 3이상이 아니면,
        int randomNum = Randoms.pickNumberInRange(1, 9); //랜덤 넘버를 뽑는다.
        if (!numbers.contains(randomNum)) { //만약 뽑힌 랜덤넘버가 컴퓨터 리스트 안에 없으면,
            numbers.add(randomNum); //랜덤 넘버를 집어넣는다.
        }
    }
    return numbers;
}
List<Integer> computers = gameService.putComputerNumbers(); //시작하자마자 컴퓨터 용 숫자 생성
for(Integer i: computers){
    System.out.print(i);
}

Controller에서 컴퓨터용 숫자를 생성한다. 그런데, 처음에는 Computer 라는 도메인을 만들어서 생성자에 이 기능을 넣었지만,, 딱히 다른 멤버변수가 필요없다고 생각해서 이렇게 했는데 맞는 지 모르겠다.

최근에 알았던 getter? 함수의 남용에서, 객체에 메세지를 보낸다고 했는데, 여기서도 그렇게 해야되나 고민이 된다.

나중에 리팩토링 하게 되면 고민해 봐야겠다..