[이펙티브 자바] 아이템 38. 확장할 수 있는 열거 타입이 필요하면 인터페이스를 사용하라

June·2022년 3월 9일
0

[이펙티브자바]

목록 보기
35/72

열거 타입은 보통은 확장에 적합하지 않다.

확장할 수 있는 열거타입이 필요할 때도 있는데 연산 코드가 그 예시다. 사용자 확장 연산을 추가할 수 있도록 열어주는 것이다.

열거 타입이 임의의 인터페이스를 구현하면 된다.

인터페이스를 이용해 확장 가능 열거 타입을 흉내냈다.

public interface Operation {
    double apply(double x, double y);
}
public enum BasicOperation implements Operationn {
    PLUS("+") {
        public double apply(double x, double y) { return x + y; }
    },
    MINUS("-") {
        public double apply(double x, double y) { return x - y; }
    },
    TIMES("*") {
        public double apply(double x, double y) { return x * y; }
    },
    DIVIDE("/") {
        public double apply(double x, double y) { return x / y; }
    };
    
    private final String symbol;
    
    BasicOperation(String symbol) {
        this.symbol = symbol;
    }
    
    @Override
    public String toString() {
        return symbol;
    }
}

Operation은 확장할 수 있고, 이 렇게 하면 Operation을 구현한 또 다른 열거타입을 정희해 대체할 수 있다.

public enum ExtendedOperation implements Operation {
    EXP("^") {
        public double apply(double x, double y) {
            return Math.pow(x, y);
        }
    },
    REMAINDER("%") {
        public double apply(double x, double y) {
            return x % y;
        }
    };
    
    private final String symbol;
    ...
}

inteface를 구현하는 여러 enum들에 접근할 수 있다.

public static void main(String[] args) {
    double x = 10;
    double y = 2;
    test(Arrays.asList(ExtendedOperation.values()), x, y);
}

public static void test(Collection<? extends Operation> opSet, double x, double y) {
    for (Operation op : opSet) {
        System.out.printf("%f %s %f = %f%n", x, op, y, op.apply(x, y));
    }
}

단점은 같은 interface를 implements하는 구현체 enum끼리는 상속이 불가능하다.
공통 부분이 많지 않다면 같은 interface내에서 디폴트 메서드로 구현하고, 공통 부분이 많다면 별도의 도우미 클래스나 정적 도우미 메서드로 분리하자.

0개의 댓글