자바 플레이그라운드 미션1-1 문자열 계산기(afterFeedback)

이호석·2022년 5월 15일
0

문자열 계산기(beforeFeedback)

이제 막 시작이고 코드에 정답은 없기에 너무 많은 시간을 투자하는 것은 지양하기로 했다. 다른 분에게 해준 피드백을 참고해서 하나의 클래스 안에 만들어야 한다는 생각은 버리고 계산 과정을 새로 만들었다. 또 ExceptionTest를 만들어 예외에 대한 테스트를 세분화하였다.

다시쓰는 경험할 객체지향 생활 체조 원칙
이번 과정을 통해 연습할 원칙은 다음 두 가지이다.
규칙 1: 한 메서드에 오직 한 단계의 들여쓰기만 한다.
규칙 2: else 예약어를 쓰지 않는다.
이 같은 원칙 아래에서 *메소드의 라인 수를 15라인이 넘지 않도록 구현한다.

왜 저 15라인을 못 본 걸까... 이번에는 제대로 적용시켰다!

Calculator.java

public class Calculator {

    public int execute() {
        Scanner scanner = new Scanner(System.in);
        String value;
        try {
            value = scanner.nextLine();
        }catch (NoSuchElementException e){
            throw new NoSuchElementException("공백은 입력할 수 없습니다.");
        }
        scanner.close();
        String[] values = value.split(" ");

        return throwMethod(values);
    }

    public int throwMethod(String[] values){
        try {
            return calculate(values);
        } catch (ArrayIndexOutOfBoundsException e) {
            throw new ArrayIndexOutOfBoundsException("입력이 잘못되었습니다.");
        } catch (NumberFormatException e) {
            throw new NumberFormatException("숫자 자리에 다른 문자를 입력했거나 띄워쓰기가 잘못되었습니다.");
        }
    }

    public int calculate(String[] values) {
        Operator operator;
        int result = Integer.parseInt(values[0]);
        int nextValue;
        for (int i = 1; i < values.length; i += 2) {
            String symbol = values[i];
            nextValue = Integer.parseInt(values[i + 1]);

            operator = Operator.findOperator(symbol);
            result = operator.operate(result, nextValue);
        }
        return result;
    }

}

Operator.java

public enum Operator {
    ADD("+", (first, second) -> first + second),
    SUBTRACT("-", (first, second) -> first - second),
    MULTIPLY("*", (first, second) -> first * second),
    DIVIDE("/", (first, second) -> {
        if (second == 0) {
            throw new ArithmeticException("0으로 나눌 수 없습니다.");
        }
        return first / second;
    });

    private String symbol;
    private BiFunction<Integer, Integer, Integer> operation;

    Operator(String symbol, BiFunction<Integer, Integer, Integer> operation){
        this.symbol = symbol;
        this.operation = operation;
    }

    public int operate(int first, int second){
        return operation.apply(first, second);
    }

    public static Operator findOperator(String symbol){
        for(Operator operator : Operator.values()) {
            if (symbol.equals(operator.symbol)) {
                return operator;
            }
        }
        throw new IllegalArgumentException("잘못된 연산자입니다.");
    }
}

테스트

예외가 아닌 계산 테스트는 기존과 달라진 점이 없으므로 ExceptionTest.java만 업로드하였다.

ExceptionTest.java

public class ExceptionTest {

    Calculator calculator = new Calculator();

    public static void inputHandling(String userInput) {
        InputStream in = new ByteArrayInputStream(userInput.getBytes());
        System.setIn(in);
    }

    @Test
    void inputBlank(){
        inputHandling("");
        assertThatThrownBy(() -> calculator.execute())
                .isInstanceOf(NoSuchElementException.class)
                .hasMessage("공백은 입력할 수 없습니다.");
    }

    @Test
    @DisplayName("계산 형식이 잘못된 입력")
    void wrongInput(){
        inputHandling("1 * 0 /");
        assertThatThrownBy(() -> calculator.execute())
                .isInstanceOf(ArrayIndexOutOfBoundsException.class)
                .hasMessage("입력이 잘못되었습니다.");
    }

    @Test
    void wrongOperator(){
        inputHandling("1 C 2");
        assertThatThrownBy(() -> calculator.execute())
                .isInstanceOf(IllegalArgumentException.class)
                .hasMessage("잘못된 연산자입니다.");
    }

    @Test
    void wrongNumber() {
        inputHandling("ㅁ * 2");
        assertThatThrownBy(() -> calculator.execute())
                .isInstanceOf(NumberFormatException.class)
                .hasMessage("숫자 자리에 다른 문자를 입력했거나 띄워쓰기가 잘못되었습니다.");
    }
}

미션1-1후기

사용자 입력같이 세부적인 것이 정해진 것이 없어 처음에 어떻게 시작해야 할지 몰라 당황했던 기억이 난다. 요구사항이 자세했으면 편했겠지만, 1부터 100까지 모든 것을 다 정해주고 그 안에서만 행동하면 그것은 기계와 다름없다(사실 정해진 대로 하는게 편하긴 하지만..). 어서 빨리 미션 1-2인 숫자야구 게임을 구현한뒤 공통피드백을 보고싶다!

0개의 댓글