본문 바로가기
카테고리 없음

Enum

by 이상한나라의개발자 2023. 12. 11.

많이들 enum 이 type을 정의 하는 기능으로 알고 계실텐데요. enum은 강력한 다형성을 제공 합니다.

enum에서 다형성을 사용하면 각 열거형 상수마다 동작을 정의할 수 있습니다. 

 

먼저 enum 을 타입 형태로만 사용했을 경우입니다. if 문이 여러개 작성되며 소스가 어려워 집니다.

 

public enum CalculateType2 {
    ADD,
    MULTIPLY,
    DIVIDE,
}

public class Client2 {
    public int someMethod(CalculateCommand2 calculateCommand) {
        if ( calculateCommand.getCalculateType() == CalculateType2.ADD ) {
            return calculateCommand.getNum1() + calculateCommand.getNum2();
        } else if ( calculateCommand.getCalculateType() == CalculateType2.MULTIPLY ) {
            return calculateCommand.getNum1() * calculateCommand.getNum2();
        } else if ( calculateCommand.getCalculateType() == CalculateType2.DIVIDE ) {
            return calculateCommand.getNum1() / calculateCommand.getNum2();
        } else {
            throw new RuntimeException("Unknown calculate type: " + calculateCommand.getCalculateType());
        }
    }
}

 

 

다형성을 구현하기 위해, 우리는 추상 메서드를 enum에 추가할 것이며 각 열거형 상수에서 이 추상 메더드를 오버라이드할 것입니다.

예를 들어 간단한 계산기를 만들어 볼 것인데요. 이 계산기는 다양한 연산을 지원해야 합니다. 이를 위해 Calculate 라는 enum을 정의하고 각 연산에 해당하는 다형적인 동작을 정의해 보겠습니다.

 

public enum Calculate1 {
    ADD {
        @Override
        public double apply(double x, double y) {
            return x + y;
        }

    },
    MULTIPLY {
        @Override
        public double apply(double x, double y) {
            return x * y;
        }

    },
    DIVIDE {
        @Override
        public double apply(double x, double y) {
            return x / y;
        }

    };
    public abstract double apply(double x, double y);
}

public class CalculateMain1 {
    public static void main(String[] args) {
        double add = Calculate1.ADD.apply(2, 5);
        double multiply = Calculate1.MULTIPLY.apply(2, 5);

        System.out.println("add = " + add);
        System.out.println("multiply = " + multiply);
    }
}

 

 

함수형 표현으로 개선해 보겠습니다.

 

public enum CalculateType {
    ADD((num1, num2) -> num1 + num2),
    DIVIDE((num1, num2) -> num1 / num2),
    MINUS((num1, num2) -> num1 - num2),
    MULTIPLY((num1, num2) -> num1 * num2);

    private final BiFunction<Integer, Integer, Integer> expression;

    CalculateType(BiFunction<Integer, Integer, Integer> calculate) {
        this.expression = calculate;
    }

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


public class CalculateCommand {

    private final CalculateType calculateType;
    private final int num1;
    private final int num2;

    public CalculateCommand(CalculateType calculateType, int num1, int num2) {
        this.calculateType = calculateType;
        this.num1 = num1;
        this.num2 = num2;
    }

    public CalculateType getCalculateType() {
        return calculateType;
    }

    public int getNum1() {
        return num1;
    }

    public int getNum2() {
        return num2;
    }
}


public class CalculateMain {

    public static void main(String[] args) {
        CalculateCommand calculateCommand = new CalculateCommand(CalculateType.MULTIPLY, 2, 5);
        Client client = new Client();
        int i = client.someMethod(calculateCommand);
        System.out.println("i = " + i);
    }
}