Item 38. Extended Enum

ν™•μž₯ν•  수 μžˆλŠ” μ—΄κ±° νƒ€μž…μ΄ ν•„μš”ν•˜λ©΄ μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ‚¬μš©ν•˜λΌ.

μ—΄κ±° νƒ€μž…μ— 단점 쀑 ν•˜λ‚˜λŠ” ν™•μž₯이 λΆˆκ°€λŠ₯ν•˜λ‹€λŠ” 것이닀. μ—΄κ±° νƒ€μž…μ„ ν™•μž₯ν•˜λŠ” 방법은 μ—†μ§€λ§Œ, μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ‚¬μš©ν•˜λ©΄ λΉ„μŠ·ν•œ 효과λ₯Ό λ‚Ό 수 μžˆλ‹€. λŒ€λΆ€λΆ„μ˜ μƒν™©μ—μ„œλŠ” μ—΄κ±° νƒ€μž…μ„ ν™•μž₯ν•˜λŠ” 것이 쒋지 μ•Šμ§€λ§Œ, ν™•μž₯ν•  수 μžˆλŠ” μ—΄κ±° νƒ€μž…μ΄ ν•„μš”ν•˜λ‹€λ©΄ μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ‚¬μš©ν•˜μž. λŒ€ν‘œμ μΈ 예둜 μ—°μ‚° μ½”λ“œλ₯Ό λ‚˜νƒ€λ‚΄λŠ” μ—΄κ±° νƒ€μž…μ΄ μžˆλ‹€.

interface Operation {
    double apply(double x, double y);
}

enum BasicOperation implements Operation {
    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;
    }
}

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;

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

    @Override
    public String toString() {
        return symbol;
    }
}

μΈν„°νŽ˜μ΄μŠ€μ˜ Operation을 ν™•μž₯ν•˜μ—¬, 이 μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ—°μ‚°μ˜ νƒ€μž…μœΌλ‘œ μ‚¬μš©ν•œ μ—΄κ±° νƒ€μž… BasicOperation을 μ •μ˜ν–ˆλ‹€. μ΄λ ‡κ²Œ ν•˜λ©΄ λ‹€μŒκ³Ό 같은 이점을 얻을 수 μžˆλ‹€.

  • apply λ©”μ„œλ“œκ°€ μΈν„°νŽ˜μ΄μŠ€μ— μ„ μ–Έλ˜μ–΄ μžˆμ–΄ λ³„λ„λ‘œ 좔상 λ©”μ„œλ“œλ₯Ό μ„ μ–Έν•  ν•„μš”κ°€ μ—†μŒ

  • μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œ μ—΄κ±° νƒ€μž…μ„ λ§Œλ“€μ–΄ μ—°μ‚° μ½”λ“œλ₯Ό μ‰½κ²Œ μΆ”κ°€ 및 λŒ€μ²΄ κ°€λŠ₯

μ•„λž˜ μ½”λ“œλŠ” μΈν„°νŽ˜μ΄μŠ€λ₯Ό ν™•μž₯ν•œ ν™•μž₯된 μ—°μ‚° μ½”λ“œλ₯Ό μ μš©ν•œ μ˜ˆμ‹œμ΄λ‹€.

import java.util.Collections;

class Main {
    public static void main(String[] args) {
        double x = 2.0;
        double y = 4.0;
        test1(BasicOperation.class, x, y);
        test1(ExtendedOperation.class, x, y);
        test2(Arrays.asList(ExtendedOperation.values()), x, y);
    }

    /**
     * @param opEnumType: class λ¦¬ν„°λŸ΄μ„ λ„˜κ²¨ ν™•μž₯된 μ—΄κ±° νƒ€μž…μ˜ Class 객체λ₯Ό λ„˜κ²¨ ν™•μž₯된 연산듀을 μ•Œλ €μ€Œ
     * @param x
     * @param y
     * @param <T>: T extends Enum<T> & Operation -> TλŠ” μ—΄κ±° νƒ€μž…μ΄λ©΄μ„œ Operation μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œ νƒ€μž…
     */
    private static <T extends Enum<T> & Operation> void test(Class<T> opEnumType, double x, double y) {
        for (Operation op : opEnumType.getEnumConstants()) {
            System.out.printf("%f %s %f = %f%n", x, op, y, op.apply(x, y));
        }
    }

    /**
     * @param opSet: ν•œμ •μ  μ™€μΌλ“œ μΉ΄λ“œ νƒ€μž…μ„ μ‚¬μš©ν•˜μ—¬, ν™•μž₯된 μ—΄κ±° νƒ€μž…μ˜ μΈμŠ€ν„΄μŠ€ 집합을 λ°›μŒ
     * @param x
     * @param y
     */
    private static void test2(Collections<? 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));
        }
    }
}

Last updated