[JAVA] Enum

이재훈·2023년 8월 13일
0

JAVA8

목록 보기
19/22

자바와 객체지향

Enum

Enum은 단순히 데이터의 타입을 정의할 때 사용한다고 생각하기 쉽지만 간단한 문법으로 강력한 다형성을 제공해줍니다.

public enum CalculateType {
    ADD, MINUS, MULTIPLY, DIVIDE
}
public class CalculateCommand {
    private CalculateType calculateType;
    private int num1;
    private 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 Client {
    public int someMethod(CalculateCommand calculateCommand) {
        CalculateType calculateType = calculateCommand.getCalculateType();
        int num1 = calculateCommand.getNum1();
        int num2 = calculateCommand.getNum2();

        int result = 0;

        if (calculateType.equals(CalculateType.ADD)) {
            result = num1 + num2;
        } else if (calculateType.equals(CalculateType.MINUS)) {
            result = num1 - num2;
        } else if (calculateType.equals(CalculateType.MULTIPLY)){
            result = num1 * num2;
        } else if (calculateType.equals(CalculateType.DIVIDE)) {
            result = num1 / num2;
        }

        return result;
    }
}

간단한 계산기 프로그램입니다. 이 코드에서 눈여겨 보야할 점은 CalculateType으로 인해 분기가 되고 있다. enum을 어떻게 사용하는지를 보시면 됩니다.

public class EnumMain {
    public static void main(String[] args) {
        CalculateCommand calculateCommand = new CalculateCommand(
                CalculateType.ADD,
                100,
                3
        );
        Client client = new Client();
        int result = client.someMethod(calculateCommand);

        System.out.println(result); // 103
    }
}

위의 클래스들을 사용하여 덧셈을 해보는 예제 코드입니다. 정상적으로 잘 동작하는 것을 확인할 수 있습니다. 하지만 이 코드를 리펙토링하여 좀 더 객체 지향적으로 바꿔보도록 하겠습니다.

Enum 좀 더 활용하기

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

    private BiFunction<Integer, Integer, Integer> expression;

    CalculateType(BiFunction<Integer, Integer, Integer> expression) {
        this.expression = expression;
    }
    
    public int calculate(int num1, int num2) {
        return this.expression.apply(num1, num2);
    }
}

enum 클래스에 코드가 복잡해진 것을 볼 수 있습니다. 단순히 타입만 지정한 것이 아니라 타입 + 연산까지 포함하여 정의를 하였습니다.

enum에 생성자가 있습니다. 각각의 타입에 대해서 괄호 부분 안에 부분을 정의한 것입니다.

BiFunction이라는 함수형 인터페이스를 선언하고 생성자에 들어온 Bifunction으로 초기화 하는 것을 확인할 수 있습니다.

enum 타입들은 하나하나가 클래스의 인스턴스와 마찬가지로 필드를 가지고 있다고 생각하면 이해가 편합니다. 생성자도 있고, 필드도 있기 때문입니다.

이제 실제로 사용을 해보도록 하겠습니다.

바뀐 client 코드

public class Client {
    public int someMethod(CalculateCommand calculateCommand) {
        CalculateType calculateType = calculateCommand.getCalculateType();
        int num1 = calculateCommand.getNum1();
        int num2 = calculateCommand.getNum2();

        int result = calculateType.calculate(num1, num2);

        return result;
    }
}

기존에 if-else if 로 지저분했던 코드가 깔끔하게 바뀐 것을 확인할 수 있습니다. 깔끔하게 바뀐 것 뿐만 아니라 더 객체지향적으로 바뀐 코드입니다.

비교

public class Client {
    public int someMethod(CalculateCommand calculateCommand) {
        CalculateType calculateType = calculateCommand.getCalculateType();
        int num1 = calculateCommand.getNum1();
        int num2 = calculateCommand.getNum2();

        int result = 0;

        if (calculateType.equals(CalculateType.ADD)) {
            result = num1 + num2;
        } else if (calculateType.equals(CalculateType.MINUS)) {
            result = num1 - num2;
        } else if (calculateType.equals(CalculateType.MULTIPLY)){
            result = num1 * num2;
        } else if (calculateType.equals(CalculateType.DIVIDE)) {
            result = num1 / num2;
        }

        return result;
    }
}

기존 Client 코드에는 CalculateType에 대해 알아야했고, if-elseif를 사용하여 연산까지 수행하였습니다.

public class Client {
    public int someMethod(CalculateCommand calculateCommand) {
        CalculateType calculateType = calculateCommand.getCalculateType();
        int num1 = calculateCommand.getNum1();
        int num2 = calculateCommand.getNum2();

        int result = calculateType.calculate(num1, num2);

        return result;
    }
}

바뀐 코드에서의 Client 코드는 CalculateType에 타입들에 대해서 알 필요가 없고 CalculateType의 존재만 알면 되었습니다. 이렇게 CalculateType은 추상적인 존재가 된 것입니다.


해당 게시글은 프로그래머스 스쿨 강의
"실무 자바 개발을 위한 OOP와 핵심 디자인 패턴(푸)"
를 정리한 내용입니다. 쉽게 잘 설명해주시니 여러분도 강의를 듣는 것을 추천드립니다.

profile
부족함을 인정하고 노력하자

1개의 댓글

comment-user-thumbnail
2023년 8월 13일

정보 감사합니다.

답글 달기