인프런 워밍업 클럽 BE - 5일차 과제

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

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

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

 

[제시된 코드]

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

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

 


우선, main 함수에 때려넣은 그대로 기능에 따라서 함수만 분리를 해보았다.

public class Main {
    private static final int DICE_SIDES = 6;

    public static void main(String[] args) {
        System.out.print("숫자를 입력하세요 : ");
        Scanner scanner = new Scanner(System.in);
        int rolls = scanner.nextInt(); // 변수 명확하게 지정
        int[] results = rollDice(rolls);
        printResults(results);
    }

    private static int[] rollDice(int rolls) {
        int[] results = new int[DICE_SIDES];
        for (int i=0; i<rolls; i++) {
            int result = (int) (Math.random() * DICE_SIDES);
            results[result]++;
        }
        return results;
    }

    private static void printResults(int[] results) {
        for (int i=0; i<DICE_SIDES; i++) {
            System.out.printf("%d은 %d번 나왔습니다.\n", i+1, results[i]);
        }
    }
}

우선 메인 함수에서 주사위를 몇 번 받을지에 대한 변수로 rolls 를 설정해주면서, 변수명을 명확하게 변경해주었다.

또한, 메인에서는 로직을 모두 삭제하고 입력 받기, 주사위 던지기, 결과 출력하기만 수행한다. 그리고 각 로직들은 함수로 분리하였다.

int[] rollDice(int rolls) 함수에서는 입력한 숫자만큼 주사위를 돌리고, 그 결과를 results에 담는 함수이다.

DICE_SIDES 라는 상수를 설정해서, 만약 주사위의 종류가 달라진다면 상수만 변경해주면 함수를 수정해 줄 필요가 없게 되었다.

그리고 출력을 위해 printResults 함수를 분리시켰다. 이 또한, DICE_SIDES 크기만큼 출력하면 되므로 결과값을 돌면서 출력해주는 함수를 만들었다.

근데 여기서 다시 한 번 거슬리는건 모든게 main 함수에 때려박아져 있는것이다. 이는 객체지향프로그래밍 관점과 맞지 않는다. 그렇기 때문에 객체지향적인 프로그래밍을 위해 이를 클래스 단위로 분리를 해보도록 하겠다.

우선, 주사위와 관련된 프로그래밍이므로, Dice 라는 클래스를 생성하였다. 그리고 나머지 함수들과 결과는 모두 이 주사위와 관련된 함수들이므로 Dice 클래스는 이와 같이 작성하였다.

import java.util.Scanner;

public class Dice {
    private static final int SIDES = 12;

    private int roll() {
        return (int) (Math.random() * SIDES);
    }

    private int[] rollDice(int rolls) {
        int[] results = new int[SIDES];
        for (int i=0; i < rolls; i++) {
            int result = this.roll();
            results[result]++;
        }
        return results;
    }

    private void printResults(int[] results) {
        for (int i = 0; i < results.length; i++) {
            System.out.printf("%d은 %d번 나왔습니다.\n", i + 1, results[i]);
        }
    }

    public void startRollDice() {
        System.out.print("숫자를 입력하세요 : ");
        Scanner scanner = new Scanner(System.in);
        int rolls = scanner.nextInt();

        Dice dice = new Dice();
        int[] results = dice.rollDice(rolls);
        printResults(results);
    }
}

Dice의 기본 정보를 정의하고, 여기서 관련 함수들을 작성하였다. 그리고 main 에서 사용할 함수는 startRollDice()로, 여기서 숫자를 입력받고 주사위를 굴리고 결과를 출력하는 것 까지 구현하여 기존의 main 함수에서 하는 기능을 수행한다.

이렇게 작성한다면 main 함수는 아래와 같이 간소화될 수 있고, 객체지향적으로 프로그램이 작성되었다.

public class Main {
    public static void main(String[] args) {
        Dice dice = new Dice();
        dice.startRollDice();
    }
}

 

댓글을 작성해보세요.

채널톡 아이콘