[인프런 워밍업 클럽 0기] BE 5일차 과제

김영훈·2024년 2월 23일
0
post-thumbnail

진도표 5일차와 연결됩니다.

우리는 <클린 코드>라는 개념을 배웠습니다. <클린 코드>에 대한 감각을 익히기 위해서는 어떤 코드가
좋은 코드이고, 어떤 코드가 좋지 않은 코드인지 이론적인 배경을 학습하는 것도 중요할 뿐 아니라,
다양한 코드를 읽어 보며 어떤 부분이 읽기 쉬웠는지, 어떤 부분이 읽기 어려웠는지,
읽기 어려운 부분은 어떻게 고치면 좋을지 경험해보는 과정이 필요합니다.

이번 과제는 제시된 코드를 읽어보며, 코드를 더 좋은 코드로 고쳐나가는 과정입니다. 구글에
"클린 코드" 혹은 "클린 코드 정리"를 키워드로 검색해보면, 이론적인 배경을 충분히 찾아보실 수 있습니다. 😊
그러한 내용들을 보며 제시된 코드를 더 좋은 코드로 바꿔보세요! (코드를 바꿀 때 왜 바뀐 코드가 더 좋은 코드인지 다른 사람에게 설명하신다고 생각해보시면 더욱 좋습니다.)


[제시된 코드]

  • 여러 함수로 나누어도 좋습니다! 🙂
  • 여러 클래스로 나누어도 좋습니다! 🙂

문제 1.

최대한 클린하지 않게 작성된 아래 코드는 다음과 같이 동작합니다.

  • 주어지는 숫자를 하나 받는다.
  • 해당 숫자만큼 주사위를 던져, 각 숫자가 몇 번 나왔는지 알려준다.
public class Main {
	
    pulbic static void main(String[] args) throws Exception {
    System.out.print("숫자를 입력하세요 : ");
    Scanner scanner = new Scanner(System.in);
    int a = scanner.nextInt();
    
    int r1 = 0, r2 = 0, r3 = 0, r4 = 0, r5 = 0, r6 = 0;
    
    for(int i = 0; i < a; i++){
    	double b = Math.random() * 6;
        if(b >= 0 && b < 1){
        	r1++;
        }else if(b >= 1 && b < 2){
        	r2++;
        }else if(b >= 2 && b < 3){
        	r3++;
        }else if(b >= 3 && b < 4){
        	r4++;
        }else if(b >= 4 && b < 5){
        	r5++;
        }else if(b >= 5 && b < 6){
        	r6++;
        }
    }
    System.out.printf("1은 %d번 나왔습니다.\n", r1);
    System.out.printf("2은 %d번 나왔습니다.\n", r2);
    System.out.printf("3은 %d번 나왔습니다.\n", r3);
    System.out.printf("4은 %d번 나왔습니다.\n", r4);
    System.out.printf("5은 %d번 나왔습니다.\n", r5);
    System.out.printf("6은 %d번 나왔습니다.\n", r6);
    }
}

📌 한 걸음 더!
현재 코드는 주사위가 1~6까지만 있다는 가정으로 작성되어 있습니다.
따라서 주사위가 1~12까지 있거나 1~20까지 있다면 코드를 많이 수정해야 하죠!


위의 코드를 클린하게 개선해 보았다면, 주사위의 숫자 범위가 달라지더라도 코드를 적게 수정할 수 있도록 고민해 봅시다! 😊


구현 1.


해결과정(분석)

  • Scanner

System.out.print("숫자를 입력하세요 : ");
Scanner scanner = new Scanner(System.in);
int a = scanner.nextInt();
// 스캐너 부분

💡 안내메세지를 출력하고, 스캐너를 통해 받은 값을 변수 a에 지정하고 있다.

  • Array

int r1 = 0, r2 = 0, r3 = 0, r4 = 0, r5 = 0, r6 = 0; //정적배열이랑 개념적으로 동일
    
    for(int i = 0; i < a; i++){
    	double b = Math.random() * 6;
        if(b >= 0 && b < 1){
        	r1++;
        }else if(b >= 1 && b < 2){
        	r2++;
        }else if(b >= 2 && b < 3){
        	r3++;
        }else if(b >= 3 && b < 4){
        	r4++;
        }else if(b >= 4 && b < 5){
        	r5++;
        }else if(b >= 5 && b < 6){
        	r6++;
        }
    }

💡 r1 ~ r6 부분은 배열과 동일한 개념이라고 생각해서, 배열로 바꿔야지 하고 마음 먹었다.
다만, 📌한 걸음 더!의 조건이 주사위의 숫자 범위가 달라지더라도
코드를 적게 수정할 수 있도록 해야한다 했으니, 이걸 처리하는 로직을 추가로 만들어야겠네~ 라고 생각했다.

  • Printer

 System.out.printf("1은 %d번 나왔습니다.\n", r1);
 System.out.printf("2은 %d번 나왔습니다.\n", r2);
 System.out.printf("3은 %d번 나왔습니다.\n", r3);
 System.out.printf("4은 %d번 나왔습니다.\n", r4);
 System.out.printf("5은 %d번 나왔습니다.\n", r5);
 System.out.printf("6은 %d번 나왔습니다.\n", r6);

💡 반복문으로 처리하면 되겠다고 생각했다.


해결과정(구현)

  • Scanner

public class InputScanner {
    public static int Input(String message) {
        System.out.print(message);
        Scanner scanner = new Scanner(System.in);
        return scanner.nextInt();
    }
}

💡 입력받을 값에 대한 안내메세지를 출력하고, 입력받은 값을 반환하게 만들었다.

  • Array

public class My_Dice {
    
    private final int diceRange;
    
    public My_Dice(int diceRange) {
        this.diceRange = diceRange;
    }
    
    public int[] rolling(int how_many) {
        int[] gameResult = new int[diceRange];
        for (int i = 0; i < how_many; i++) {
            int randomNumber = (int)(Math.random() * diceRange);
            gameResult[randomNumber]++;
        }
        return gameResult;
    }
}

💡 생성자로 주사위 범위를 받아서, 그 크기만큼 배열을 생성한다.
Math.random() * diceRange의 값에서 정수부분만 받아오면 0 부터 diceRange - 1 의 값을 얻을 수 있다.
예를 들어 diceRange의 값이 6이라면 , 0 에서 5 사이의 값을 얻을 수 있다.
이걸 Index로 활용하여 나온 횟수만큼 gameResult 배열에 저장한다.

  • Printer

public class Printer {
  public static void printResults(int[] gameResult) {
   for (int i = 0; i < gameResult.length; i++) 
   System.out.println("[ "+(i + 1) +" ] "+ "나온 횟수 : " + gameResult[i]);
  } 
}

💡 gameResult 배열을 받아서 출력한다.

  • Main

 public class Main {
    public static void main(String[] args) {
        // 범위 정하기
        int diceRange = InputScanner.Input("주사위의 범위를 정해주세요. (입력: 6 -> 1부터 6까지) : ");
        My_Dice dice = new My_Dice(diceRange); // 전달받은 숫자가 주사위 범위
        int how_many = InputScanner.Input("주사위를 던질 횟수를 입력하세요: ");
        int[] gameResult = dice.rolling(how_many); //횟수만큼 주사위를 던져서 결과저장
        Printer.printResults(gameResult); //결과를 출력
    }
}
  • 결과

💡 보기 좋게 Printer부분에서 약간의 꾸밈효과를 추가하였다.


후기

막상 해결하고 나니 diceRange를 입력받는 형태가 아니라 직접 설정하게 만들었어야 했나? 싶었다.
만약 그렇다면 Main에서 범위 지정 메세지를 삭제하고 diceRange를 원하는 범위로 직접 설정하게 바꿔주면 될거같다.


0개의 댓글