item 38 dodo4513 - JAVA-JIKIMI/EFFECTIVE-JAVA3 GitHub Wiki

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

  • μ—΄κ±° νƒ€μž…μ€ 거의 λͺ¨λ“  μƒν™©μ—μ„œ 이 μ±… μ΄ˆνŒμ—μ„œ μ†Œκ°œν•œ νƒ€μž… μ•ˆμ „ μ—΄κ±° νŒ¨ν„΄(typesafe enum pattern)보닀 μš°μˆ˜ν•˜λ‹€.
  • 단, μ˜ˆμ™Έκ°€ ν•˜λ‚˜ μžˆμœΌλ‹ˆ, νƒ€μž… μ•ˆμ „ μ—΄κ±° νŒ¨ν„΄μ€ ν™•μž₯ν•  수 μžˆμœΌλ‚˜ μ—΄κ±° νƒ€μž…μ€ 그럴 수 μ—†λ‹€λŠ” 점이닀. 달리 λ§ν•˜λ©΄, νƒ€μž… μ•ˆμ „ μ—΄κ±° νŒ¨ν„΄μ€ μ—΄κ±°ν•œ 값듀을 κ·ΈλŒ€λ‘œ κ°€μ Έμ˜¨ λ‹€μŒ 값을 더 μΆ”κ°€ν•˜μ—¬ λ‹€λ₯Έ λͺ©μ μœΌλ‘œ μ“Έ 수 μžˆλŠ” 반면, μ—΄κ±° νƒ€μž…μ€ κ·Έλ ‡κ²Œ ν•  수 μ—†λ‹€λŠ” λœ»μ΄λ‹€.
  • μ‹€μˆ˜λ‘œ μ΄λ ‡κ²Œ μ„€κ³„ν•œ 것은 μ•„λ‹ˆλ‹€. 사싀 λŒ€λΆ€λΆ„ μƒν™©μ—μ„œ μ—΄κ±° νƒ€μž…μ„ ν™•μž₯ν•˜λŠ” 건 쒋지 μ•Šμ€ 생각이닀. ν™•μž₯ν•œ νƒ€μž…μ˜ μ›μ†ŒλŠ” 기반 νƒ€μž…μ˜ μ›μ†Œλ‘œ μ·¨κΈ‰ν•˜μ§€λ§Œ κ·Έ λ°˜λŒ€λŠ” μ„±λ¦½ν•˜μ§€ μ•ŠλŠ”λ‹€λ©΄ μ΄μƒν•˜μ§€ μ•Šμ€κ°€!
  • 기반 νƒ€μž…κ³Ό ν™•μž₯된 νƒ€μž…λ“€μ˜ μ›μ†Œ λͺ¨λ‘λ₯Ό μˆœνšŒν•  방법도 λ§ˆλ•…μΉ˜ μ•Šλ‹€.
  • λ§ˆμ§€λ§‰μœΌλ‘œ, ν™•μž₯성을 높이렀면 κ³ λ €ν•  μš”μ†Œκ°€ λŠ˜μ–΄λ‚˜ 섀계와 κ΅¬ν˜„μ΄ 더 λ³΅μž‘ν•΄μ§„λ‹€.

typesafe enum pattern이 뭐지?

public class Suit {
    private final String name;

    public static final Suit CLUBS =new Suit("clubs");
    public static final Suit DIAMONDS =new Suit("diamonds");
    public static final Suit HEARTS =new Suit("hearts");
    public static final Suit SPADES =new Suit("spades");

    private Suit(String name){
        this.name =name;
    }
    public String toString(){
        return name;
    }
}
  • μ˜›λ‚  μžλ°” 1.5 λ²„μ „μ—μ„œ μœ„μ™€ 같이 ν”νžˆ μ‚¬μš©ν•˜λ˜ νŒ¨ν„΄μ΄λΌκ³  함.

ν™•μž₯ν•  수 μžˆλŠ” μ—΄κ±°νƒ€μž…μ΄ μ–΄μšΈλ¦¬λŠ” μ“°μž„

  • λ°”λ‘œ μ—°μ‚° μ½”λ“œ(operation code ν˜Ήμ€ opcode)λ‹€. μ—°μ‚° μ½”λ“œμ˜ 각 μ›μ†ŒλŠ” νŠΉμ • 기계가 μˆ˜ν–‰ν•˜λŠ” 연산을 λœ»ν•œλ‹€(μ•„μ΄ν…œ 34의 Operation νƒ€μž…λ„ 그쀑 ν•˜λ‚˜λ‘œ, κ°„λ‹¨ν•œ κ³„μ‚°κΈ°μ˜ μ—°μ‚° κΈ°λŠ₯을 μ˜λ―Έν–ˆλ‹€). μ΄λ”°κΈˆ APIκ°€ μ œκ³΅ν•˜λŠ” κΈ°λ³Έ μ—°μ‚° μ™Έ 에 μ‚¬μš©μž ν™•μž₯ 연산을 μΆ”κ°€ν•  수 μžˆλ„λ‘ μ—΄μ–΄μ€˜μ•Ό ν•  λ•Œκ°€ μžˆλ‹€.

  • λ‹€ν–‰νžˆ μ—΄κ±° νƒ€μž…μœΌλ‘œ 이 효과λ₯Ό λ‚΄λŠ” 멋진 방법이 μžˆλ‹€. κΈ°λ³Έ μ•„μ΄λ””μ–΄λŠ” μ—΄κ±° νƒ€μž…μ΄ μž„μ˜μ˜ μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•  수 μžˆλ‹€λŠ” 사싀을 μ΄μš©ν•˜λŠ” 것이닀.

ν™•μž₯ κ°€λŠ₯ μ—΄κ±°νƒ€μž…μ„ 흉내낸 μΈν„°νŽ˜μ΄μŠ€

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

public 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;
    }
}
  • μ—΄κ±° νƒ€μž…μΈ BasicOperation은 ν™•μž₯ν•  수 μ—†μ§€λ§Œ μΈν„°νŽ˜μ΄μŠ€μΈ Operation은 ν™•μž₯ν•  수 있고, 이 μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ—°μ‚°μ˜ νƒ€μž…μœΌλ‘œ μ‚¬μš©ν•˜λ©΄ λœλ‹€. μ΄λ ‡κ²Œ ν•˜λ©΄ Operation을 κ΅¬ν˜„ν•œ 또 λ‹€λ₯Έ μ—΄κ±° νƒ€μž…μ„ μ •μ˜ν•΄ κΈ°λ³Έ νƒ€μž…μΈ BasicOperation 을 λŒ€μ²΄ν•  수 μžˆλ‹€.
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;
    ExtendedOperation(String symbol) {
        this.symbol = symbol;
    }
    @Override public String toString() {
        return symbol;
    }
}
  • μƒˆλ‘œ μž‘μ„±ν•œ 연산은 κΈ°μ‘΄ 연산을 μ“°λ˜ 곳이면 μ–΄λ””λ“  μ“Έ 수 μžˆλ‹€. (Basic Operation이 μ•„λ‹Œ) Operation μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ‚¬μš©ν•˜λ„λ‘ μž‘μ„±λ˜μ–΄ 있기만 ν•˜λ©΄λœλ‹€. applyκ°€ μΈν„°νŽ˜μ΄μŠ€(Operation)에 μ„ μ–Έλ˜μ–΄ μžˆμœΌλ‹ˆ μ—΄κ±° νƒ€μž…μ— λ”°λ‘œ 좔상 λ©”μ„œλ“œλ‘œ μ„ μ–Έν•˜μ§€ μ•Šμ•„λ„ λœλ‹€.

  • μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ΄μš©ν•΄ ν™•μž₯ κ°€λŠ₯ν•œ μ—΄κ±° νƒ€μž…μ„ 흉내 λ‚΄λŠ” 방식에도 ν•œ 가지 μ‚¬μ†Œν•œ λ¬Έμ œκ°€ μžˆλ‹€. λ°”λ‘œ μ—΄κ±° νƒ€μž…λΌλ¦¬ κ΅¬ν˜„μ„ 상속할 수 μ—†λ‹€λŠ” 점이닀. μ•„λ¬΄μƒνƒœμ—λ„ μ˜μ‘΄ν•˜μ§€ μ•ŠλŠ” κ²½μš°μ—λŠ” λ””ν΄νŠΈ κ΅¬ν˜„(μ•„μ΄ν…œ 20)을 μ΄μš©ν•΄ μΈν„°νŽ˜μ΄μŠ€μ— μΆ”κ°€ν•˜λŠ” 방법이 μžˆλ‹€.

핡심정리

μ—΄κ±° νƒ€μž… μžμ²΄λŠ” ν™•μž₯ν•  수 μ—†μ§€λ§Œ, μΈν„°νŽ˜μ΄μŠ€μ™€ κ·Έ μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜λŠ” κΈ°λ³Έ μ—΄κ±°νƒ€μž…μ„ ν•¨κ»˜ μ‚¬μš©ν•΄ 같은 효과λ₯Ό λ‚Ό 수 μžˆλ‹€.

μ΄λ ‡κ²Œ ν•˜λ©΄ ν΄λΌμ΄μ–ΈνŠΈλŠ” 이 μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•΄ μžμ‹ λ§Œμ˜ μ—΄κ±° νƒ€μž…(ν˜Ήμ€ λ‹€λ₯Έ νƒ€μž…)을 λ§Œλ“€ 수 μžˆλ‹€.
그리고 APIκ°€ (κΈ°λ³Έ μ—΄κ±° νƒ€μž…μ„ 직접 λͺ…μ‹œν•˜μ§€ μ•Šκ³ ) μΈν„°νŽ˜μ΄μŠ€ 기반으둜 μž‘μ„±λ˜μ—ˆλ‹€λ©΄
κΈ°λ³Έ μ—΄κ±° νƒ€μž…μ˜ μΈμŠ€ν„΄μŠ€κ°€ μ“°μ΄λŠ” λͺ¨λ“  곳을 μƒˆλ‘œ ν™•μž₯ν•œ μ—΄κ±° νƒ€μž…μ˜ μΈμŠ€ν„΄μŠ€λ‘œ λŒ€μ²΄ν•΄ μ‚¬μš©ν•  수 μžˆλ‹€.

⚠️ **GitHub.com Fallback** ⚠️