계산기 작성 With Exception(2)

이동규·2023년 4월 9일

static 메서드

  • 전에 수정했던 Calculator Class 에서 생성자에 따라 Parser Class를 수정해보았다.
  • 여기서 더 나아가 수정해본 코드는 Calculator Class를 불러들이지 않고 Parser Class 내부에서 static 메서드를 추가하여서 동작하도록 해보았다.
package Calculator;
import java.util.regex.Pattern;

public class Parser {
    private static final String OPERATION_REG = "[+\\-*/]";
    private static final String NUMBER_REG = "^[0-9]*$";
		
		private static AbstractOperation operation;
    private static int firstNumber;
    private static int secondNumber;

    public static void setOperation(AbstractOperation operation) {
        Parser.operation = operation;
    }

    public static double calculate(int firstNumber, int secondNumber) {
        return Parser.operation.operate(Parser.firstNumber, Parser.secondNumber);
    }

    public Parser parseFirstNum(String firstInput) throws Exception{
        if (!Pattern.matches(NUMBER_REG, firstInput)) {
            throw new BadInputException("정수값");
        }
		this.firstNumber = Integer.parseInt(firstInput);

        return this;
    }

    public Parser parseSecondNum(String secondInput) throws Exception {
        if (!Pattern.matches(NUMBER_REG, secondInput)) {
            throw new BadInputException("정수값");
        }
		this.secondNumber = Integer.parseInt(secondInput);

        return this;
    }

    public Parser parseOperator(String operationInput) throws Exception {
        if (!Pattern.matches(OPERATION_REG, operationInput)) {
            throw new BadInputException("사칙 연산의 연산자");
        }

        switch (operationInput) {
						case "+" -> Parser.setOperation(new AddOperation());
            case "-" -> Parser.setOperation(new SubOperation());
            case "*" -> Parser.setOperation(new MultiOperation());
            case "/" -> Parser.setOperation(new DivOperation());
        }

        return this;
    }

    public double executeCalculator() {
				return Parser.calculate(this.firstNumber, this.secondNumber);
    }
}
  • CalculatorApp
package Calculator;

import java.util.Scanner;

public class CalculatorApp {

    public static boolean start() throws Exception{
        Parser parser = new Parser();
        Scanner scanner = new Scanner(System.in);

        System.out.println("첫번째 숫자를 입력해주세요!");
        String firstInput = scanner.nextLine();
        parser.parseFirstNum(firstInput);

        System.out.println("연산자를 입력해주세요!");
        String operator = scanner.nextLine();
        parser.parseOperator(operator);

        System.out.println("두번째 숫자를 입력해주세요!");
        String secondInput = scanner.nextLine();
        parser.parseSecondNum(secondInput);

        System.out.println("연산 결과 : " + parser.executeCalculator());
        return true;
    }
}
  • 이렇게 수정해보고 static 사용에 대한 어느정도의 이해가 따라왔다.
    1. static을 사용하면 this를 사용하지 못함
      • static 메소드는 객체가 생성되기 이전에 메모리에 올라가기 때문에, 객체 내부에 있는 인스턴스 변수에 직접 접근할 수 없다.
      • 클래스 변수(static 변수)와 클래스 메소드(static 메소드)에는 접근이 가능
    2. 이러면 객체 지향적으로 짜는 방법이 아니므로 유지보수와 확장성이 떨어짐

Interface를 사용하여 수정해보기

  • Interface를 사용하여 계산기 logic을 짜는 것은 추상화를 사용하여 짜는 것과 굉장히 유사했다.
  • 하지만
public void parseFirstNum(String firstInput) throws Exception{
        if (!Pattern.matches(NUMBER_REG, firstInput)) {
            throw new BadInputException("정수값");
        }
        this.calculator.setFirstNumber(Integer.parseInt(firstInput));
			
				return this;
    }

이 코드에서 "Return value of the method is never used" 경고가 뜨는 것을 확인하였는데, 이러한 경고가 뜨는 이유는 parseFirstNum()메소드가 this를 반환하고 있지만, 해당 반환값을 변수에 저장하거나 메소드 호출의 인자로 전달하지 않고 있어서 이 경고가 나타나고 있다.

→ this에 대한 이해도가 더 필요해 보인다.

  • 또한, 전체적인 코드를 살펴보면 연산자를 입력하여 그 연산자에 맞게 각각의 연산자의 클래스로 연산자가 보내지도록 로직을 설정하였는데 처음에 나는 Interface 속에 사칙 연산을 넣어서 인터페이스 속에서 하나씩 꺼내지도록 로직을 설정하고 싶었다. 하지만, 연산자를 입력하는 과정에서 처음에 작성했던 인터페이스 로직은 원하는 연산을 불러 바로 계산 과정을 거쳐 값을 출력하도록 작성이 되어있었다. 이 때문에 연산자를 입력했을 때 그 입력된 연산자가 인터페이스 속 해당되는 연산자로 찾아가고 연산 결과 상에서 연산을 진행하는 세분화 과정에서 막혔다. → 이를 해결하기 위해 인터페이스 속에는 추상 메서드를 집어 넣고 각각의 연산을 수행하는 클래스를 만들어서 인터페이스를 구현하였다.
profile
진짜 개발자가 되고 싶다

0개의 댓글