๐Ÿ“– Effective java item 34 - int ์ƒ์ˆ˜ ๋Œ€์‹  ์—ด๊ฑฐ ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜๋ผ


Enum ?

[Java] Enum ์—ด๊ฑฐํ˜•

int Enum Pattern์˜ ๋‹จ์ 

ํƒ€์ž… ์•ˆ์ „์„ ๋ณด์žฅํ•  ๋ฐฉ๋ฒ•์ด ์—†๋‹ค.

public static final int APPLE_FUJI = 0;
public static final int APPLE_PIPPIN = 1;
public static final int APPLE_GRANNY_SMITH = 2;

public static final int ORANGE_NAVEL = 0;
public static final int ORANGE_TEMPLE = 1;
public static final int ORANGE_BLOOD = 2;

์œ„์™€ ๊ฐ™์€ ์˜ˆ์ œ์—์„œ๋Š” ์‚ฌ๊ณผ์šฉ ์ƒ์ˆ˜ ์ด๋ฆ„์€ ๋ชจ๋‘ APPLE_๋กœ ์‹œ์ž‘,
์˜ค๋ Œ์ง€์šฉ ์ƒ์ˆ˜๋Š” ORANGE_๋กœ ์‹œ์ž‘ํ•œ๋‹ค.
์ด๋Š” ํ‘œํ˜„๋ ฅ์ด ์ข‹์ง€ ์•Š๋‹ค.
์ž๋ฐ”๊ฐ€ ์ •์ˆ˜ ์—ด๊ฑฐ ํŒจํ„ด์„ ์œ„ํ•œ ๋ณ„๋„ ์ด๋ฆ„ ๊ณต๊ฐ„์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค.

ํ”„๋กœ๊ทธ๋žจ์ด ๊นจ์ง€๊ธฐ ์‰ฝ๋‹ค.

ํ‰๋ฒ”ํ•œ ์ƒ์ˆ˜๋ฅผ ๋‚˜์—ดํ•œ ๊ฒƒ๋ฟ์ด๋ผ ์ปดํŒŒ์ผํ•˜๋ฉด ๊ทธ ๊ฐ’์ด ํด๋ผ์ด์–ธํŠธ ํŒŒ์ผ์— ๊ทธ๋Œ€๋กœ ์ƒˆ๊ฒจ์ง„๋‹ค.
์ƒ์ˆ˜์˜ ๊ฐ’์ด ๋ฐ”๋€Œ๋ฉด ํด๋ผ์ด์–ธํŠธ๋„ ๋ฐ˜๋“œ์‹œ ๋‹ค์‹œ ์ปดํŒŒ์ผํ•ด์•ผ ํ•œ๋‹ค.

๋ฌธ์ž์—ด๋กœ ์ถœ๋ ฅํ•˜๊ธฐ ๊นŒ๋‹ค๋กญ๋‹ค.

๊ฐ’์„ ์ถœ๋ ฅํ•˜๊ฑฐ๋‚˜ ๋””๋ฒ„๊ฑฐ๋กœ ์‚ดํŽด๋ณด๋ฉด ๋‹จ์ง€ ์ˆซ์ž๋กœ๋งŒ ๋ณด์—ฌ์„œ ์ฉ ๋„์›€์ด ๋˜์ง€ ์•Š๋Š”๋‹ค.
๊ฐ™์€ ์ •์ˆ˜ ์—ด๊ฑฐ ๊ทธ๋ฃน์— ์†ํ•œ ๋ชจ๋“  ์ƒ์ˆ˜๋ฅผ ์ˆœํšŒํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ๋งˆ๋•…ํ•˜์ง€ ์•Š๋‹ค.
๋˜ ์ด ์•ˆ์— ์ƒ์ˆ˜๊ฐ€ ๋ช‡ ๊ฐœ์ธ์ง€๋„ ์•Œ ์ˆ˜ ์—†๋‹ค.

์ •์ˆ˜ ๋Œ€์‹  ๋ฌธ์ž์—ด ์ƒ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ณ€ํ˜• ํŒจํ„ด์€?

๋” ๋‚˜์˜๋‹ค. ์ƒ์ˆ˜์˜ ์˜๋ฏธ๋ฅผ ์ถœ๋ ฅํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์€ ์ข‹์ง€๋งŒ,
๋ฌธ์ž์—ด ์ƒ์ˆ˜๋ฆ ์ด๋ฆ„ ๋Œ€์‹  ๋ฌธ์ž์—ด ๊ฐ’์„ ๊ทธ๋Œ€๋กœ ํ•˜๋“œ์ฝ”๋”ฉํ•˜๊ฒŒ ๋งŒ๋“ค๊ธฐ ๋–„๋ฌธ์ด๋‹ค.
๋ฌธ์ž์—ด์— ์˜คํƒ€๊ฐ€ ์žˆ์–ด๋„ ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ํ™•์ธํ•  ๊ธธ์ด ์—†์œผ๋‹ˆ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋Ÿฐํƒ€์ž„ ๋ฒ„๊ทธ๊ฐ€ ์ƒ๊ธด๋‹ค.
๋˜ ๋ฌธ์ž์—ด ๋น„๊ต๋Š” ๋น„๊ต์  ์„ฑ๋Šฅ ์ €ํ•˜๋ฅผ ์ผ์œผํ‚จ๋‹ค.

์—ด๊ฑฐ ํƒ€์ž…(Enum)

public enum Apple {FUJI, PIPPIN, GRANNY_SMITH}
public enum Orange {NAVEL, TEMPLE, BLOOD}

C, C++ ๊ฐ™์€ ๋‹ค๋ฅธ ์–ธ์–ด์˜ ์—ด๊ฑฐ ํƒ€์ž…๊ณผ ๋‹ค๋ฅธ ์ ์€ ์ž๋ฐ”์˜ ์—ด๊ฑฐ ํƒ€์ž…์€ ์™„์ „ํ•œ ํ˜•ํƒœ์˜ ํด๋ž˜์Šค๋‹ค.

์—ด๊ฑฐ ํƒ€์ž… ์ž์ฒด๋Š” ํด๋ž˜์Šค๋ฉฐ, ์ƒ์ˆ˜ ํ•˜๋‚˜๋‹น ์ž์‹ ์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ํ•˜๋‚˜์”ฉ ๋งŒ๋“ค์–ด
public static final ํ•„๋“œ๋กœ ๊ณต๊ฐœํ•œ๋‹ค.
์—ด๊ฑฐ ํƒ€์ž…์€ ๋ฐ–์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ์ƒ์„ฑ์ž๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์‚ฌ์‹ค์ƒ final์ด๋‹ค.
๋”ฐ๋ผ์„œ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ธ์Šคํ„ด์Šค๋ฅผ ์ง์ ‘ ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜ ํ™•์žฅํ•  ์ˆ˜ ์—†์œผ๋‹ˆ ์—ด๊ฑฐ ํƒ€์ž… ์„ ์–ธ์œผ๋กœ
๋งŒ๋“ค์–ด์ง„ ์ธ์Šคํ„ด์Šค๋“ค์€ ๋”ฑ ํ•˜๋‚˜์”ฉ๋งŒ ์กด์žฌํ•จ์ด ๋ณด์žฅ๋œ๋‹ค.
์ฆ‰ ์—ด๊ฑฐ ํƒ€์ž…์€ ์ธ์Šคํ„ด์Šค ํ†ต์ œ๋œ๋‹ค.
์‹ฑ๊ธ€ํ„ด์€ ์›์†Œ๊ฐ€ ํ•˜๋‚˜๋ฟ์ธ ์—ด๊ฑฐํƒ€์ž…์ด๋ผ ํ•  ์ˆ˜ ์žˆ๊ณ ,
์—ด๊ฑฐ ํƒ€์ž…์€ ์‹ฑ๊ธ€ํ„ด์„ ์ผ๋ฐ˜ํ™”ํ•œ ํ˜•ํƒœ๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

์ปดํŒŒ์ผํƒ€์ž„ ํƒ€์ž… ์•ˆ์ •์„ฑ ์ œ๊ณต

public enum Apple {FUJI, PIPPIN, GRANNY_SMITH}
public enum Orange {NAVEL, TEMPLE, BLOOD}

์œ„ ์ฝ”๋“œ์—์„œ Apple์˜ ์—ด๊ฑฐ ํƒ€์ž…์„ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ›๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์„ ์–ธํ–ˆ๋‹ค๋ฉด,
๊ฑด๋„ค๋ฐ›์€ ์ฐธ์กฐ๋Š” Apple์˜ ์„ธ ๊ฐ€์ง€ ๊ฐ’ ์ค‘ ํ•˜๋‚˜์ž„์ด ํ™•์‹คํ•˜๋‹ค.
๋‹ค๋ฅธ ํƒ€์ž…์˜ ๊ฐ’์„ ๋„˜๊ธฐ๋ ค ํ•˜๋ฉด ์ปดํŒŒ์ผ ์˜ค๋ฅ˜๊ฐ€ ๋‚œ๋‹ค.
ํƒ€์ž…์ด ๋‹ค๋ฅธ ์—ด๊ฑฐ ํƒ€์ž… ๋ณ€์ˆ˜์— ํ• ๋‹นํ•˜๋ ค ํ•˜๊ฑฐ๋‚˜
๋‹ค๋ฅธ ์—ด๊ฑฐ ํƒ€์ž…์˜ ๊ฐ’ ๋ผ๋ฆฌ == ์—ฐ์‚ฐ์ž๋กœ ๋น„๊ตํ•˜๋ ค๋Š” ๊ผด์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๊ฐ์ž์˜ ์ด๋ฆ„ ๊ณต๊ฐ„์ด ์กด์žฌํ•œ๋‹ค.

๋•Œ๋ฌธ์— ์ด๋ฆ„์ด ๊ฐ™์€ ์ƒ์ˆ˜๋„ ํ‰ํ™”๋กญ๊ฒŒ ๊ณต์กดํ•œ๋‹ค.
์—ด๊ฑฐ ํƒ€์ž…์— ์ƒˆ๋กœ์šด ์ƒ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์ˆœ์„œ๋ฅผ ๋ฐ”๊ฟ”๋„ ๋‹ค์‹œ ์ปดํŒŒ์ผ ํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.
์—ด๊ฑฐ ํƒ€์ž…์— ์ƒˆ๋กœ์šด ์ƒ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์ˆœ์„œ๋ฅผ ๋ฐ”๊ฟ”๋„ ๋‹ค์‹œ ์ปดํŒŒ์ผ ํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.
๊ณต๊ฐœ๋˜๋Š” ๊ฒƒ์ด ์˜ค์ง ํ•„๋“œ์˜ ์ด๋ฆ„๋ฟ์ด๋‹ˆ ,
์ •์ˆ˜ ์—ด๊ฑฐ ํŒจํ„ด๊ณผ ๋‹ฌ๋ฆฌ ์ƒ์ˆ˜ ๊ฐ’์ด ํด๋ผ์ด์–ธํŠธ๋กœ ์ปดํŒŒ์ผ ๋˜์–ด ๊ฐ์ธ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๋ฌธ์ž์—ด๋กœ ์ถœ๋ ฅํ•˜๊ธฐ ์ ํ•ฉํ•˜๋‹ค.

์—ด๊ฑฐํƒ€์ž…์˜ toString()์€ ์ถœ๋ ฅํ•˜๊ธฐ์— ์ ํ•ฉํ•œ ๋ฌธ์ž์—ด์„ ๋‚ด์–ด์ค€๋‹ค.

์ž„์˜์˜ ๋ฉ”์„œ๋“œ, ํ•„๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์ž„์˜์˜ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

Object ๋ฉ”์„œ๋“œ๋“ค์„ ๋†’์€ ํ’ˆ์งˆ๋กœ ๊ตฌํ˜„ํ•ด๋†จ๊ณ , Comparable๊ณผ Serializable์„
๊ตฌํ˜„ํ–ˆ์œผ๋ฉฐ, ๊ทธ ์ง๋ ฌํ™” ํ˜•ํƒœ๋„ ์›ฌ๋งŒํผ ๋ณ€ํ˜•์„ ๊ฐ€ํ•ด๋„ ๋ฌธ์ œ์—†์ด ๋™์ž‘ํ•˜๊ฒŒ๋” ๊ตฌํ˜„ํ•ด๋†จ๋‹ค.

์—ด๊ฑฐ ํƒ€์ž… ์‚ฌ์šฉ ๊ฒฝ์šฐ

๊ฐ ์ƒ์ˆ˜์™€ ์—ฐ๊ด€๋œ ๋ฐ์ดํ„ฐ๋ฅผ ํ•ด๋‹น ์ƒ์ˆ˜ ์ž์ฒด์— ๋‚ด์žฌ์‹œํ‚ฌ ๋•Œ

์˜ˆ์ œ๋กœ ๋“ค์—ˆ๋˜ Apple๊ณผ Orange์— ๊ณผ์ผ ์ƒ‰์„ ์•Œ๋ ค์ฃผ๊ฑฐ๋‚˜,
๊ณผ์ผ ์ด๋ฏธ์ง€๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค๋ฉด, ์—ด๊ฑฐ ํƒ€์ž…์— ์ด ๊ธฐ๋Šฅ์„ ๋ฉ”์„œ๋“œ๋กœ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ฐ€์žฅ ๋‹จ์ˆœํ•˜๊ฒŒ๋Š” ๊ทธ์ € ์ƒ์ˆ˜์˜ ๋ชจ์Œ์ผ ๋ฟ์ธ ์—ด๊ฑฐ ํƒ€์ž…์ด์ง€๋งŒ,
๊ณ ์ฐจ์›์˜ ์ถ”์ƒ ๊ฐœ๋… ํ•˜๋‚˜๋ฅผ ์™„๋ฒฝํžˆ ํ‘œํ˜„ํ•ด๋‚ผ ์ˆ˜๋„ ์žˆ๋‹ค.

Example

ํƒœ์–‘๊ฐœ์˜ ํ–‰์„ฑ์—๋Š” ๊ฐ๊ฐ ์งˆ๋Ÿ‰๊ณผ ๋ฐ˜์ง€๋ฆ„์ด ์žˆ๊ณ , ์ด ๋‘ ์†์„ฑ์„ ์ด์šฉํ•ด ํ‘œ๋ฉด์ค‘๋ ฅ์„ ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ๋‹ค.
๋”ฐ๋ผ์„œ ์–ด๋–ค ๊ฐ์ฒด์˜ ์งˆ๋Ÿ‰์ด ์ฃผ์–ด์ง€๋ฉด ๊ทธ ๊ฐ์ฒด๊ฐ€ ํ–‰์„ฑ ํ‘œ๋ฉด์— ์žˆ์„ ๋•Œ์˜ ๋ฌด๊ฒŒ๋„ ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ๋‹ค.
ํ‘œ๋ฉด ์ค‘๋ ฅ์„ ๊ณ„์‚ฐํ•ด ์ €์žฅํ•œ ์ด์œ ๋Š” ๋‹จ์ˆœํžˆ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•ด์„œ๋‹ค.

@Getter
public enum Planet {
    MERCURY(3.302e+23, 2.439e6),
    VENUS(4.869e+24, 6.052e6),
    EARTH(5.975e+24, 6.378e6),
    MARS(6.419e+23, 3.393e6),
    JUPITER(1.899e+27, 7.149e7),
    SATURN(5.685e+26, 6.027e7),
    URANUS(8.683e+25, 2.556e7),
    NEPTUNE(1.024e+26, 2.447e7);
    
    private final double mass;            // ์งˆ๋Ÿ‰(๋‹จ์œ„: ํ‚ฌ๋กœ๊ทธ๋žจ)
    private final double radius;          // ๋ฐ˜์ง€๋ฆ„(๋‹จ์œ„: ๋ฏธํ„ฐ)
    private final double surfaceGravity;  // ํ‘œ๋ฉด์ค‘๋ ฅ(๋‹จ์œ„: m / s^2)
    
    // ์ค‘๋ ฅ์ƒ์ˆ˜ (๋‹จ์œ„: m^3 / kg s^2)
    private static final double G = 6.67300E-11;
    
    // ์ƒ์„ฑ์ž
    Planet(double mass, double radius) {
        this.mass = mass;
        this.radius = radius;
        this.surfaceGravity = G * mass / (radius * radius);
    }
    
    public double surfaceWeight(double mass) {
        return mass * surfaceGravity;
    }
}

์—ด๊ฑฐ ํƒ€์ž… ์ƒ์ˆ˜ ๊ฐ๊ฐ์„ ํŠน์ • ๋ฐ์ดํ„ฐ์™€ ์—ฐ๊ด€์ง€์œผ๋ ค๋ฉด ์ƒ์„ฑ์ž์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„ ์ธ์Šคํ„ด์Šค ํ•„๋“œ์— ์ €์žฅํ•˜๋ฉด ๋œ๋‹ค.

์—ด๊ฑฐ ํƒ€์ž…์€ ๊ทผ๋ณธ์ ์œผ๋กœ ๋ถˆ๋ณ€์ด๋ผ ๋ชจ๋“  ํ•„๋“œ๋Š” final์ด์–ด์•ผ ํ•œ๋‹ค.

ํ•„๋“œ๋ฅผ public์œผ๋กœ ์„ ์–ธํ•ด๋„ ๋˜์ง€๋งŒ private๋กœ ๋‘์–ด ๋ณ„๋„์˜ public ์ ‘๊ทผ์ž ๋ฉ”์„œ๋“œ๋ฅผ ๋‘๋Š”๊ฒŒ ๋‚ซ๋‹ค.

์–ด๋–ค ๊ฐ์ฒด์˜ ์ง€๊ตฌ์—์„œ์˜ ๋ฌด๊ฒŒ๋ฅผ ์ž…๋ ฅ๋ฐ›์•„ ํ–‰์„ฑ์—์„œ์˜ ๋ฌด๊ฒŒ๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ์ผ์„ ๋‹ค์Œ๊ฐ™์ด ์งง๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

public classs WeightTable {
	public static void main(String[] args) {
    	double earthWeight = Double.parseDouble(args[0]);
        double mass = earthWeight / Planet.EARTH.surfaceGravity();
        for (Planet p : Palanet.values()) 
        	System.out.println("%s์—์„œ ๋ฌด๊ฒŒ๋Š” %f์ด๋‹ค. %n", p, p.surfaceWeight(mass));
    }
}

์ง€์›ํ•˜๋Š” ๋ฉ”์„œ๋“œ

  • values() : ์ž์‹  ์•ˆ์— ์ •์˜๋œ ์ƒ์ˆ˜๋“ค์˜ ๊ฐ’์„ ๋ฐฐ์—ด์— ๋‹ด์•„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ •์  ๋ฉ”์„œ๋“œ, ๊ฐ’๋“ค์€ ์„ ์–ธ๋œ ์ˆœ์„œ๋กœ ์ €์žฅ
  • valueOf() : ์ƒ์ˆ˜ ์ด๋ฆ„์„ ์ž…๋ ฅ๋ฐ›์•„ ๊ทธ ์ด๋ฆ„์— ํ•ด๋‹นํ•˜๋Š” ์ƒ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜
  • toString() : ์ƒ์ˆ˜ ์ด๋ฆ„์„ ๋ฌธ์ž์—ด๋กœ ๋ฐ˜ํ™˜, ์›ํ•˜๋Š” ๋Œ€๋กœ ์žฌ์ •์˜๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.
  • fromString() : toString์ด ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฌธ์ž์—ด์„ ํ•ด๋‹น ์—ด๊ฑฐ ํƒ€์ž… ์ƒ์ˆ˜๋กœ ๋ณ€ํ™˜

์—ด๊ฑฐ ํƒ€์ž…์—์„œ ์ƒ์ˆ˜๋ฅผ ํ•˜๋‚˜ ์ œ๊ฑฐํ•˜๋ฉด?

์ œ๊ฑฐํ•œ ์ƒ์ˆ˜๋ฅผ ์ฐธ์กฐํ•˜์ง€ ์•Š๋Š” ํด๋ผ์ด์–ธํŠธ์—๋Š” ์•„๋ฌด ์˜ํ–ฅ์ด ์—†๋‹ค.
์ œ๊ฑฐ๋œ ์ƒ์ˆ˜๋ฅผ ์ฐธ์กฐํ•˜๋Š” ํด๋ผ์ด์–ธํŠธ๋Š” ์ปดํŒŒ์ผํƒ€์ž„์— ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ด ์ด๋ฅผ ์žก์„ ์ˆ˜ ์žˆ๋‹ค.

์ƒ์ˆ˜๋งˆ๋‹ค ๋™์ž‘์ด ๋‹ฌ๋ผ์ ธ์•ผ ํ•  ๊ฒฝ์šฐ

์‚ฌ์น™์—ฐ์‚ฐ ๊ณ„์‚ฐ๊ธฐ์˜ ์—ฐ์‚ฐ ์ข…๋ฅ˜๋ฅผ ์—ด๊ฑฐ ํƒ€์ž…์œผ๋กœ ์„ ์–ธํ•˜๊ณ , ์‹ค์ œ ์—ฐ์‚ฐ๊นŒ์ง€ ์—ด๊ฑฐ ํƒ€์ž… ์ƒ์ˆ˜๊ฐ€ ์ง์ ‘ ์ˆ˜ํ–‰ํ•˜๊ธฐ๋กœ ํ•œ๋‹ค.

public enum Operation {
    PLUS, MINUS, TIMES, DIVIDE
}

switch ๋ฌธ์œผ๋กœ ๋ถ„๊ธฐ์ฒ˜๋ฆฌ

/* ์ƒ์ˆ˜๊ฐ€ ๋œปํ•˜๋Š” ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. */
public double apply(double x, double y) {
    switch(this) {
        case PLUS: return x + y;
        case MINUS: return x - y;
        case TIMES: return x * y;
        case DIVIDE: return x / y;
    }
    throw new AssertionError("์•Œ ์ˆ˜ ์—†๋Š” ์—ฐ์‚ฐ: " + this);
}

์ด ๋ฐฉ๋ฒ•์˜ ๋‹จ์ ์€ ๊นจ์ง€๊ธฐ ์‰ฌ์šด ์ฝ”๋“œ๋ผ๋Š” ๊ฒƒ์ด๋‹ค.
์ƒˆ๋กœ์šด ์ƒ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ํ•ด๋‹น case ๋ฌธ๋„ ์ถ”๊ฐ€ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

ํ•˜์ง€๋งŒ ๊ธฐ์กด ์—ด๊ฑฐ ํƒ€์ž…์— ์ƒ์ˆ˜๋ณ„ ๋™์ž‘์„ ํ˜ผํ•ฉํ•ด์„œ ๋„ฃ์„ ๋•Œ๋Š” ์ข‹์€ ์„ ํƒ์ด๋‹ค.
์ถ”๊ฐ€ํ•˜๋ ค๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ์˜๋ฏธ์ƒ ์—ด๊ฑฐ ํƒ€์ž…์— ์†ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์ง์ ‘ ๋งŒ๋“  ์—ด๊ฑฐ ํƒ€์ž…์ด๋ผ๋„ ์ด ๋ฐฉ์‹์ด ์œ ์šฉํ•˜๋‹ค.

apply() ์ถ”์ƒ ๋ฉ”์„œ๋“œ ์„ ์–ธ

public enum 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;}};
    
    public abstract double apply(double x, double y);
}

apply()๊ฐ€ ์ถ”์ƒ ๋ฉ”์„œ๋“œ์ด๋ฏ€๋กœ ์žฌ์ •์˜ํ•˜์ง€ ์•Š์•˜๋‹ค๋ฉด ์ปดํŒŒ์ผ ์˜ค๋ฅ˜๋กœ ์•Œ๋ ค์ค€๋‹ค.

์ƒ์ˆ˜๋ณ„ ํด๋ž˜์Šค ๋ชธ์ฒด์™€ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉ

public enum 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;
    
    Operation(String symbol) {this.symbol = symbol;}
    
    @Override public String toString() {return symbol;}
    public abstract double apply(double x, double y);
}

์—ด๊ฑฐ ํƒ€์ž…์šฉ fromString ๋ฉ”์„œ๋“œ ๊ตฌํ˜„

private static final Map<String, Operation> stringToEnum = 
Stream.of(values()).collect(toMap(Object::toString, e -> e));

/* ์ง€์ •ํ•œ ๋ฌธ์ž์—ด์— ํ•ด๋‹นํ•˜๋Š” Operation์„ (์กด์žฌํ•œ๋‹ค๋ฉด) ๋ฐ˜ํ™˜ํ•œ๋‹ค. */
public static Optional<Operation> fromString(String symbol) {
    return Optional.ofNullable(stringToEnum.get(symbol));
}

Operation ์ƒ์ˆ˜๊ฐ€ stringToEnum ๋งต์— ์ถ”๊ฐ€๋˜๋Š” ์‹œ์ ์€ ์—ด๊ฑฐ ํƒ€์ž… ์ƒ์ˆ˜ ์ƒ์„ฑ ํ›„ ์ •์  ํ•„๋“œ๊ฐ€ ์ดˆ๊ธฐํ™” ๋  ๋•Œ์ด๋‹ค.

์œ„ ์˜ˆ์ œ๋Š” values ๋ฉ”์„œ๋“œ๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฐฐ์—ด ๋Œ€์‹  ์ŠคํŠธ๋ฆผ์„ ์‚ฌ์šฉํ–ˆ๋‹ค.

์—ด๊ฑฐ ํƒ€์ž… ์ƒ์ˆ˜๋Š” ์ƒ์„ฑ์ž์—์„œ ์ž์‹ ์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋งต์— ์ถ”๊ฐ€ํ•  ์ˆ˜ ์—†๋‹ค.
์ด๋ ‡๊ฒŒ ํ•˜๋ ค๋ฉด ์ปดํŒŒ์ผ ์˜ค๋ฅ˜๊ฐ€ ๋‚˜๋Š”๋ฐ, ์ด ๋ฐฉ์‹์ด ํ—ˆ์šฉ๋œ๋‹ค๋ฉด ๋Ÿฐํƒ€์ž„์— NullPointerException์ด ๋ฐœ์ƒํ–ˆ์„ ๊ฒƒ์ด๋‹ค.

์—ด๊ฑฐ ํƒ€์ž…์˜ ์ •์  ํ•„๋“œ ์ค‘ ์—ด๊ฑฐ ํƒ€์ž…์˜ ์ƒ์„ฑ์ž์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ์ƒ์ˆ˜ ๋ณ€์ˆ˜ ๋ฟ์ด๋‹ค.

์—ด๊ฑฐ ํƒ€์ž… ์ƒ์„ฑ์ž๊ฐ€ ์‹คํ–‰๋˜๋Š” ์‹œ์ ์—๋Š” ์ •์  ํ•„๋“œ๋“ค์ด ์•„์ง ์ดˆ๊ธฐํ™”๋˜๊ธฐ ์ „์ด๋ผ,
์ž๊ธฐ ์ž์‹ ์„ ์ถ”๊ฐ€ํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ํ•˜๋Š” ์ œ์•ฝ์ด ๊ผญ ํ•„์š”ํ•˜๋‹ค.
ํŠน์ˆ˜ํ•œ ์˜ˆ๋กœ, ์—ด๊ฑฐ ํƒ€์ž… ์ƒ์„ฑ์ž์—์„œ ๊ฐ™์€ ์—ด๊ฑฐ ํƒ€์ž…์˜ ๋‹ค๋ฅธ ์ƒ์ˆ˜์—๋„ ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋‹ค.
(์—ด๊ฑฐ ํƒ€์ž…์˜ ๊ฐ ์ƒ์ˆ˜๋Š” ํ•ด๋‹น ์—ด๊ฑฐ ํƒ€์ž…์˜ ์ธ์Šคํ„ด์Šค๋ฅผ public static final ํ•„๋“œ๋กœ ์„ ์–ธํ–ˆ๋‹ค.
์ฆ‰, ๋‹ค๋ฅธ ํ˜•์ œ ์ƒ์ˆ˜๋„ static์ด๋ฏ€๋กœ ์—ด๊ฑฐ ํƒ€์ž… ์ƒ์„ฑ์ž์—์„œ ์ •์  ํ•„๋“œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋‹ค๋Š” ์ œ์•ฝ์ด ์ ์šฉ๋œ๋‹ค.)

๋˜ํ•œ, ์œ„ ์˜ˆ์ œ์—์„œ fromString์ด Optional<Operation>์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ ๋„ ์ฃผ์˜ํ•˜์ž.
์ฃผ์–ด์ง„ ๋ฌธ์ž์—ด์ด ๊ฐ€๋ฆฌํ‚ค๋Š” ์—ฐ์‚ฐ์ด ์กด์žฌํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Œ์„ ํด๋ผ์ด์–ธํŠธ์— ์•Œ๋ฆฌ๊ณ , ๊ทธ ์ƒํ™ฉ์„ ํด๋ผ์ด์–ธํŠธ์—์„œ ๋Œ€์ฒ˜ํ•˜๋„๋ก ํ•œ ๊ฒƒ์ด๋‹ค.

๊ฐ’์— ๋”ฐ๋ผ ๋ถ„๊ธฐํ•˜์—ฌ ์ฝ”๋“œ๋ฅผ ๊ณต์œ ํ•˜๋Š” ์—ด๊ฑฐ ํƒ€์ž… - ์ข‹์€ ๋ฐฉ๋ฒ•์ธ๊ฐ€?

์ƒ์ˆ˜๋ณ„ ๋ฉ”์„œ๋“œ ๊ตฌํ˜„์—๋Š” ์—ด๊ฑฐ ํƒ€์ž… ์ƒ์ˆ˜๋ผ๋ฆฌ ์ฝ”๋“œ๋ฅผ ๊ณต์œ ํ•˜๊ธฐ ์–ด๋ ต๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค.
์˜ˆ์‹œ๋กœ ๊ธ‰์—ฌ๋ช…์„ธ์„œ์—์„œ ์“ธ ์š”์ผ์„ ํ‘œํ˜„ํ•˜๋Š” ์—ด๊ฑฐ ํƒ€์ž…์„ ์˜ˆ๋กœ ์ƒ๊ฐํ•ด ๋ณด๋ฉด, ์ง์›์˜ ๊ธฐ๋ณธ ์ž„๊ธˆ, ๊ทธ๋‚  ์ผํ•œ ์‹œ๊ฐ„์ด ์ฃผ์–ด์ง€๋ฉด ์ผ๋‹น์„ ๊ณ„์‚ฐํ•ด์ฃผ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.
์ฃผ์ค‘์— ์˜ค๋ฒ„ํƒ€์ž„์ด ๋ฐœ์ƒํ•˜๋ฉด ์ž”์—… ์ˆ˜์žฅ์ด ์ฃผ์–ด์ง€๊ณ , ์ฃผ๋ง์—๋Š” ๋ฌด์กฐ๊ฑด ์ž”์—… ์ˆ˜๋‹น์ด ์ฃผ์–ด์ง„๋‹ค.
switch ๋ฌธ์„ ์ด์šฉํ•˜๋ฉด case ๋ฌธ์„ ๋‚ ์งœ๋ณ„๋กœ ๋‘์–ด ์ด ๊ณ„์‚ฐ์„ ์‰ฝ๊ฒŒ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

enum PayrollDay {
    MONDAY, TUESDAY, WEDSDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
    
    private static final int MINS_PER_SHIFT = 8 * 60;
    
    int pay(int minutesWorked, int payRate) {
        int basePay = minutesWorked * payRate;
        
        int overtimePay;
        switch(this) {
            case SATURDAY: case SUNDAY: // ์ฃผ๋ง
                overtimePay = basePay / 2;
                break;
            default: // ์ฃผ์ค‘
                overtimePay = minutesWOrked <= MINS_PER_SHIFT ?
                0 : minutesWorked - MINS_PER_SHIFT) * payRate / 2;
        }
            
        return basePay + overtimePay;
    }
}

์ด ์ฝ”๋“œ์˜ ๋ฌธ์ œ์ ์€ ํœด๊ฐ€์™€ ๊ฐ™์€ ์ƒˆ๋กœ์šด ๊ฐ’์„ ์—ด๊ฑฐ ํƒ€์ž…์— ์ถ”๊ฐ€ํ•˜๋ ค๋ฉด ๊ทธ ๊ฐ’์„ ์ฒ˜๋ฆฌํ•˜๋Š” case๋ฌธ์„ ์žŠ์ง€ ๋ง๊ณ  ์Œ์œผ๋กœ ๋„ฃ์–ด์ค˜์•ผ ํ•œ๋‹ค.

PayrollDay์— ํ‰์ผ ์ž”์—…์ˆ˜๋‹น ๊ณ„์‚ฐ์šฉ ๋ฉ”์„œ๋“œ์ธ overtimePay๋ฅผ ๊ตฌํ˜„ํ•ด๋†“๊ณ , ์ฃผ๋ง ์ƒ์ˆ˜์—์„œ๋งŒ ์žฌ์ •์˜ํ•ด ์จ๋„, ์ƒˆ๋กœ์šด ์ƒ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด์„œ overtimePay ๋ฉ”์„œ๋“œ๋ฅผ ์žฌ์ •์˜ํ•˜์ง€ ์•Š์œผ๋ฉด ํ‰์ผ์šฉ ์ฝ”๋“œ๋ฅผ ๊ทธ๋Œ€๋กœ ๋ฌผ๋ ค๋ฐ›๊ฒŒ ๋œ๋‹ค.

์ •๋žต ์—ด๊ฑฐ ํƒ€์ž… ํŒจํ„ด

์ƒˆ๋กœ์šด ์ƒ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•  ๋•Œ ์ž”์—…์ˆ˜๋‹น โ€˜์ „๋žตโ€™์„ ์„ ํƒํ•˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
์ž”์—… ์ˆ˜๋‹น ๊ณ„์‚ฐ์„ private ์ค‘์ฒฉ ์—ด๊ฑฐ ํƒ€์ž…(PayType)์œผ๋กœ ์˜ฎ๊ธฐ๊ณ , PayrollDay ์—ด๊ฑฐ ํƒ€์ž…์˜ ์ƒ์„ฑ์ž์—์„œ ์ด ์ค‘ ์ ๋‹นํ•œ ๊ฒƒ์„ ์„ ํƒํ•œ๋‹ค.

๊ทธ๋Ÿฌ๋ฉด payrollDay ์—ด๊ฑฐ ํƒ€์ž…์€ ์ž”์—…์ˆ˜๋‹น ๊ณ„์‚ฐ์„ ๊ทธ ์ „๋žต ์—ด๊ฑฐ ํƒ€์ž…์— ์œ„์ž„ํ•˜์—ฌ, switch ๋ฌธ์ด๋‚˜ ์ƒ์ˆ˜๋ณ„ ๋ฉ”์„œ๋“œ ๊ตฌํ˜„์ด ํ•„์š” ์—†๊ฒŒ ๋œ๋‹ค.

enum PayrollDay {
    MONDAY, TUESDAY, WEDSDAY, THURSDAY, FRIDAY, 
    SATURDAY(PayTyoe.WEEKEND), SUNDAY(PayType.WEEKEND);
    
    private final PayType payType;
    
    PayrollDya(PayType payTyoe) {this.payType = payType;}
    
    int pay(int minutesWorked, int payRate) {
    	return payType.pay(minutesWorked, payRate);
    }
    
    /* ์ „๋žต ์—ด๊ฑฐ ํƒ€์ž… */
    enum PayType {
        WEEKDAY {
            int overtimePay(int minusWorked, int payRate) {
                return minusWorked <= MINS_PER_SHIFT ? 0 :
                (minusWorked - MINS_PER_SHIFT) * payRate / 2;
            }
        },
        WEEKEND {
            int overtimePay(int minusWorked, int payRate) {
                return minusWorked * payRate / 2;
            }
        };
        
        abstract int overtimePay(int mins, int payRate);
        private static final int MINS_PER_SHIFT = 8 * 60;
        
        int pay(int minsWorked, int payRate) {
            int basePay = minsWorked * payRate;
            return basePay + overtimePay(minsWorked, payRate);
        }
    }
}

ํ•„์š”ํ•œ ์›์†Œ๋ฅผ ์ปดํŒŒ์ผํƒ€์ž„์— ๋‹ค ์•Œ ์ˆ˜ ์žˆ๋Š” ์ƒ์ˆ˜ ์ง‘ํ•ฉ์ด๋ผ๋ฉด, ํ•ญ์ƒ ์—ด๊ฑฐ ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜์ž

์—ด๊ฑฐ ํƒ€์ž…์— ์ •์˜๋œ ์ƒ์ˆ˜ ๊ฐœ์ˆ˜๊ฐ€ ์˜์›ํžˆ ๊ณ ์ • ๋ถˆ๋ณ€์ผ ํ•„์š”๋Š” ์—†๋‹ค.
์—ด๊ฑฐ ํƒ€์ž…์€ ๋‚˜์ค‘์— ์ƒ์ˆ˜๊ฐ€ ์ถ”๊ฐ€๋ผ๋„ ๋ฐ”์ด๋„ˆ๋ฆฌ ์ˆ˜์ค€์—์„œ ํ˜ธํ™˜๋˜๋„๋ก ์„ค๊ณ„๋˜์—ˆ๋‹ค.

์ •๋ฆฌ

  • ์—ด๊ฑฐ ํƒ€์ž…์€ ์ •์ˆ˜ ์ƒ์ˆ˜๋ณด๋‹ค ์ฝ๊ธฐ ์‰ฝ๊ณ , ์•ˆ์ „ํ•˜๊ณ  ๊ฐ•๋ ฅํ•˜๋‹ค.
  • ์—ด๊ฑฐ ํƒ€์ž…์€ ๋ช…์‹œ์  ์ƒ์„ฑ์ž๋‚˜ ๋ฉ”์„œ๋“œ ์—†์ด ์“ฐ์ด์ง€๋งŒ, ๊ฐ ์ƒ์ˆ˜๋ฅผ ํŠน์ • ๋ฐ์ดํ„ฐ์™€ ์—ฐ๊ฒฐ์ง“๊ฑฐ๋‚˜ ์ƒ์ˆ˜๋งˆ๋‹ค ๋‹ค๋ฅด๊ฒŒ ๋™์ž‘ํ•˜๊ฒŒ ํ•  ๋•Œ ํ•„์š”ํ•˜๋‹ค.
  • ๋“œ๋ฌผ๊ฒŒ ํ•˜๋‚˜์˜ ๋ฉ”์„œ๋“œ๊ฐ€ ์ƒ์ˆ˜๋ณ„๋กœ ๋‹ค๋ฅด๊ฒŒ ๋™์ž‘ํ•ด์•ผ ํ•  ๋•Œ๋„ ์žˆ๋‹ค. ์ด๋Ÿฐ ์—ด๊ฑฐ ํƒ€์ž…์—์„œ๋Š” switch ๋ฌธ ๋Œ€์‹  ์ƒ์ˆ˜๋ณ„ ๋ฉ”์„œ๋“œ ๊ตฌํ˜„์„ ์‚ฌ์šฉํ•œ๋‹ค.
  • ์—ด๊ฑฐ ํƒ€์ž… ์ƒ์ˆ˜ ์ผ๋ถ€๊ฐ€ ๊ฐ™์€ ๋™์ž‘์„ ๊ณต์œ ํ•˜๋ฉด ์ „๋žต ์—ด๊ฑฐ ํƒ€์ž… ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜์ž.