티스토리 뷰

public class Calculator {
    public static int plus(int num1, int num2) {
        return num1 + num2;
    }
    public static int minus(int num1, int num2) {
        return num1- num2;
    }
    public static int multiply(int num1, int num2) {
        return num1 * num2;
    }
    public static int divide(int num1, int num2) {
        return num1 / num2;
    }
}
// public class StringCalculator

private int map(int num1, int num2, String operator) {
        if (operator.equals(PLUS)) {
            return Calculator.plus(num1, num2);
        }
        if (operator.equals(MINUS)) {
            return Calculator.minus(num1, num2);
        }
        if (operator.equals(MULTIPLE)) {
            return Calculator.multiply(num1, num2);
        }
        if (operator.equals(DIVIDE)) {
            return Calculator.divide(num1, num2);
        }
        throw new IllegalArgumentException();
    }

java enum을 활용해 다음과 같이 바꿀수있다.

java7이하 버전을 대상으로,
추상메소드를 이용해 상수별 메소드를 구현하였다.

public enum Operator {
    PLUS("+") {
        @Override
        public int calculate(int num1, int num2) {
            return num1 + num2;
        }
    },
    MINUS("-") {
        @Override
        public int calculate(int num1, int num2) {
            return num1 - num2;
        }
    },
    MULTIPLY("*") {
        @Override
        public int calculate(int num1, int num2) {
            return num1 * num2;
        }
    },
    DIVIDE("/") {
        @Override
        public int calculate(int num1, int num2) {
            return num1 / num2;
        }
    };

    private String symbol;

    Operator(String symbol) {
        this.symbol = symbol;
    }

    public abstract int calculate(int num1, int num2);
}
public class StringCalculator {
    private final static String PLUS = "+";
    private final static String MINUS = "-";
    private final static String MULTIPLE = "*";
    private final static String DIVIDE = "/";

    private static Map<String, Operator> operators = new HashMap<>();

    static {
        operators.put(PLUS, Operator.PLUS);
        operators.put(MINUS, Operator.MINUS);
        operators.put(MULTIPLE, Operator.MULTIPLY);
        operators.put(DIVIDE, Operator.DIVIDE);
    }

    ...

    private int calculate(int num1, int num2, String operator) {
        return operators.get(operator).calculate(num1, num2);
    }
}

java8이상이라면 다음과 같이,
함수형 인터페이스(Functional Interface)와 람다식(Lambda)을 이용할수있다.

public enum Operator {
    PLUS("+", (num1, num2) -> num1 + num2),
    MINUS("-", (num1, num2) -> num1 - num2),
    MULTIPLY("*", (num1, num2) -> num1 * num2),
    DIVIDE("/", (num1, num2) -> num1 / num2);

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

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

    public int calculate(int num1, int num2) {
        return expression.apply(num1, num2);
    }
}

추가로
입력한 operator를 매칭하고 연결하는 부분을, StringCalculator에서 enum으로 옮겨
StringCalculator를 더 간단히 줄일수있었다.

public class StringCalculator {
    /*private final static String PLUS = "+";
    private final static String MINUS = "-";
    private final static String MULTIPLE = "*";
    private final static String DIVIDE = "/";

    private static Map<String, Operator> operators = new HashMap<>();

    static {
        operators.put(PLUS, Operator.PLUS);
        operators.put(MINUS, Operator.MINUS);
        operators.put(MULTIPLE, Operator.MULTIPLY);
        operators.put(DIVIDE, Operator.DIVIDE);
    }*/

    private int calculate(int num1, int num2, String operator) {
        return Operator.calculate(num1, num2, operator);
    }
}
public enum Operator {
    PLUS("+", (num1, num2) -> num1 + num2),
    MINUS("-", (num1, num2) -> num1 - num2),
    MULTIPLY("*", (num1, num2) -> num1 * num2),
    DIVIDE("/", (num1, num2) -> num1 / num2);

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

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

    public static int calculate(int num1, int num2, String inputSymbol) {
        for (Operator operator : Operator.values()) {
            if (operator.match(inputSymbol)) {
                return operator.expression.apply(num1, num2);
            }
        }
        throw new IllegalArgumentException();
    }

    private boolean match(String inputSymbol) {
        return this.symbol.equals(inputSymbol);
    }
}
  • enum 활용전 "+"와 같은 string을 operator라는 변수명으로 사용하다, Operator enum 생성후 이와 헷갈려 input string을 symbol과 같이 변수명 수정해서 구분

19.5.19 추가 피드백

calculate()의 계산과 찾는 기능(for와 if)을 분리시키면 좋을것 같다.

참고자료

Java Enum 활용기 - 우아한형제들 기술 블로그
nextree/Java: enum의 뿌리를 찾아서
함수형 인터페이스(Functional Interface)
if문 없이 문자열 계산하기 (feat. 전략패턴, Enum)

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함