[TIL] Enum 타입

정석·2024년 7월 29일

TIL

목록 보기
6/40
post-thumbnail

코드의 가독성과 수정의 편리함을 위해 사용!

signal 값을 통한 Switch case 문으로 사칙연산을 수행하는 코드를 아래와 같이 작성 할 수 있다.
보다시피 중복되는 코드가 보이기도하며 signal 에 사칙연산 기호가 들어가므로 실제로 어떤 의미인지 모를 수도 있다.

한 번 enum 타입을 활용하여 수정해보자!

  • 수정 전 사칙연산 로직
        switch (signal) {
            case '+':
                AddOperator addOperator = new AddOperator(left, right);
                result = addOperator.operate();
                break;

            case '-':
                SubtractOperator subtractOperator = new SubtractOperator(left, right);
                result = subtractOperator.operate();
                break;

            case '*':
                MultiplyOperator multiplyOperator = new MultiplyOperator(left, right);
                result = multiplyOperator.operate();
                break;

            case '/':
                if (right == 0) {
                    throw new DivideException("0으로 나눌 수 없습니다. ");
                }
                
				else {
                    DivideOperator divideOperator = new DivideOperator(left, right);
                    result = divideOperator.operate();
                
                }
                break;

            case '%' :
                ModOperator modOperator = new ModOperator(left, right);
                result = modOperator.operate();
        }
        

Enum 타입 생성

public enum OperatorType {
   PLUS('+'),
   SUB('-'),
   MUL('*'),
   DIV('/'),
   MOD('%');

   public final char signal;

   OperatorType(char signal) {
       this.signal = signal;
   }
}

enum 타입은 상수 형식으로 만들어진다. 그래서 한 번 생성되면 값은 바뀌지 않는다.
실제로 생성할 때 위와 같이 데이터를 추가할 수 있다.

각 상수에 대입되는 데이터(value)에 사칙연산 기호(char signal)를 넣어보았다.

여기서 Enum 에서 제공하는 메서드를 알아보자!

1. values()

return -> enum[ ]

이 메서드는 해당하는 enum 타입에 존재하는 모든 상수 배열을 반환한다.

그래서 만약 아래 처럼 사용하면

for (OperatorType type : values()) {
	System.out.print(type + " ");
 
// 출력 : PLUS SUB MUL DIV MOD

이렇게 출력 되게 된다.

더 나아가서 각 상수 안에 저장된 value 또한 알고 싶다면?
Enum 클래스에서 getter을 만들어 주고 반환하면 된다!

public enum OperatorType {
    PLUS('+'),
    SUB('-'),
    MUL('*'),
    DIV('/'),
    MOD('%');

    public final char signal;
    
    public char getSignal() { // getter 생성!
    	return signal;
    }

    OperatorType(char signal) {
        this.signal = signal;
    }
 }
for (OperatorType type : values()) {
	System.out.print(type.getSignal() + " "); // values 값 가져오기
 
// 출력 : + - * / %

2. valueOf()

return -> enum

만약, PLUS 라고 적힌 enum 을 찾고자 할 때 이렇게 사용하면 해당하는 enum 상수가 불러온다.

OperatorType plus = Operator.valueOf("PLUS");

그래서 이와 같이 Enum 클래스를 활용해서 switch 문을 보다 간결하게 바꿀 수 있었다.

public Operator getOperatorBySignal() {
        OperatorType operatorType = OperatorType.find(signal);

        switch(operatorType) {
            case PLUS :
                return new AddOperator(left, right);

            case SUB :
                return new SubtractOperator(left, right);

            case MUL :
                return new MultiplyOperator(left, right);

            case DIV :
                return new DivideOperator(left, right);

            case MOD :
                return new ModOperator(left, right);

            default:
                return null;
        }
    }

일단, signal 값을 이용해서 OperatorType 즉 enum 타입을 찾고자 find 메서드를 enum 클래스에서 아래와 같이 만들어준다.

public static OperatorType find(char signal) {
        for (OperatorType type : values()) {
            if (type.signal == signal) {
                return type;
            }
        }
        throw new IllegalArgumentException("잘못된 기호");
    }

여기서 찾게 되는 enum 상수를 이용해 switch 문을 돌게 되며 각 사칙연산을 수행하는 로직을 지나간다.


결론

enum 클래스를 처음 생성해봤다. 뭔가 되게 효율적으로 쓸 수 있을 거 같은데 아직은 그림이 안그려진다.
처음 사용해보니 뭐가 좋은지도 잘 모르겠다.

velog 를 처음 접할 때도 그랬다. 글 하나 게시하는 시간만 한시간이 걸렸고 마크다운 언어도 너무 익숙치 않아 '아 그냥 쓰지 말까?' 고민하기도 했다. 하지만 지금은 게시글 하나 작성하는 건 누워서 떡 먹기다. 단지 귀찮아서 안 쓸뿐^^

이 또한 언젠간 익숙하게 활용할 거라 미래의 나를 자신한다.

0개의 댓글