Programming/Java

[Java] Enum

soeun2537 2024. 11. 5. 00:01
πŸ’­ λ“€μ–΄κ°€λ©°
ν”„λ¦¬μ½”μŠ€ 3μ£Όμ°¨ κ³Όμ œμ—μ„œ "Java Enum을 μ μš©ν•˜μ—¬ ν”„λ‘œκ·Έλž¨μ„ κ΅¬ν˜„ν•œλ‹€."λΌλŠ” ν”„λ‘œκ·Έλž˜λ° μš”κ΅¬ 사항이 μžˆμ—ˆλ‹€. 이전에도 Enum을 μ‚¬μš©ν•΄ λ³Έ 적은 μžˆμ§€λ§Œ, 이번 과제λ₯Ό μ§„ν–‰ν•˜λ©΄μ„œ Enum을 μ •ν™•νžˆ μ΄ν•΄ν•˜μ§€ λͺ»ν•œ μƒνƒœλ‘œ μ‚¬μš©ν•΄ μ™”λ‹€λŠ” 생각이 λ“€μ—ˆλ‹€. λ‹¨μˆœνžˆ μš”κ΅¬μ‚¬ν•­ λ•Œλ¬Έμ— μ‚¬μš©ν•˜κΈ°λ³΄λ‹€, μ œλŒ€λ‘œ μ•Œκ³  ν™œμš©ν•˜μžλŠ” 마음으둜 Enum을 λ‹€μ‹œ κ³΅λΆ€ν–ˆλ‹€. Enum에 λŒ€ν•΄ 잘 μ •λ¦¬λœ μΈνŒŒλ‹˜μ˜ 글을 μ°Έκ³ ν•˜μ—¬ κ³Όμ œμ— μ μš©ν•΄ λ³΄μ•˜κ³ , 이번 κΈ€μ—μ„œλŠ” ν•΄λ‹Ή 뢀뢄을 μ •λ¦¬ν•˜κ³  과제λ₯Ό μ§„ν–‰ν•˜λ©΄μ„œ λŠλ‚€ Enum의 μž₯점을 μ •λ¦¬ν•˜λ €κ³  ν•œλ‹€.

 

βœ… μ΄μ „μ˜ μƒμˆ˜ 관리 방식

β–Ά static final μƒμˆ˜

final ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ ν•˜λ“œ μ½”λ”©λœ 값을 μƒμˆ˜λ‘œ μΆ”μΆœν•˜λŠ” 방식이닀.

πŸ”½ 2μ£Όμ°¨ 과제(μžλ™μ°¨ κ²½μ£Ό): static final μƒμˆ˜

public class Car {
    public static final int MOVE_THRESHOLD = 4;
    public static final int RANDOM_MIN = 0;
    public static final int RANDOM_MAX = 9;
    public static final int MOVE_INCREMENT = 1;

    ...

    public void moveConditionally() {
        int random = Randoms.pickNumberInRange(RANDOM_MIN, RANDOM_MAX);
        if (random >= MOVE_THRESHOLD) {
            increaseDistance();
        }
    }

    private void increaseDistance() {
        currentDistance += MOVE_INCREMENT;
    }
}

πŸ”½ μž₯점

  • final둜 μ„ μ–Έλœ λ³€μˆ˜λŠ” ν•œ 번 μ΄ˆκΈ°ν™”λ˜λ©΄ λ³€κ²½ν•  수 μ—†λ‹€.
  • static을 ν•¨κ»˜ μ‚¬μš©ν•˜λ©΄ λ©”λͺ¨λ¦¬μ— ν•œ 번만 ν• λ‹Ήλ˜μ–΄ λ©”λͺ¨λ¦¬ 효율이 λ†’μ•„μ§„λ‹€.

πŸ”½ 단점

  • μ ‘κ·Ό μ œμ–΄μž μ„€μ •μœΌλ‘œ 인해 가독성이 λ–¨μ–΄μ§ˆ 수 μžˆλ‹€.
  • λ‹€μ–‘ν•œ μ’…λ₯˜μ˜ μƒμˆ˜λ₯Ό ν•œ κ³³μ—μ„œ κ΄€λ¦¬ν•˜κΈ° μ–΄λ ΅κ³ , μ—¬λŸ¬ μƒμˆ˜λ₯Ό ν•˜λ‚˜μ˜ ν΄λž˜μŠ€μ— λͺ¨μœΌλ©΄ μ½”λ“œκ°€ λ³΅μž‘ν•΄μ§ˆ 수 μžˆλ‹€.

 

β–Ά μΈν„°νŽ˜μ΄μŠ€ μƒμˆ˜

μƒμˆ˜λ₯Ό κ΄€λ¦¬ν•˜λŠ” 또 λ‹€λ₯Έ λ°©λ²•μœΌλ‘œ μƒμˆ˜λ§Œ ν¬ν•¨λœ μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ§Œλ“œλŠ” 방식이닀. μΈν„°νŽ˜μ΄μŠ€λŠ” 별도 μ œμ–΄μž 없이 μƒμˆ˜λ§Œμ„ μ •μ˜ν•  수 μžˆλ‹€.

πŸ”½ 2μ£Όμ°¨ 과제(μžλ™μ°¨ κ²½μ£Ό): μΈν„°νŽ˜μ΄μŠ€ μƒμˆ˜

public interface CarConstants {
    int MOVE_THRESHOLD = 4;
    int RANDOM_MIN = 0;
    int RANDOM_MAX = 9;
    int MOVE_INCREMENT = 1;
}

πŸ”½ μž₯점

  • ν΄λž˜μŠ€μ—μ„œ implements CarConstantsλ₯Ό 톡해 μƒμˆ˜λ₯Ό 직접 μ‚¬μš©ν•  수 μžˆμ–΄ νŽΈλ¦¬ν•˜λ‹€.
  • μƒμˆ˜λ₯Ό λ³„λ„μ˜ νŒŒμΌμ— λΆ„λ¦¬ν•¨μœΌλ‘œμ¨, 클래슀 νŒŒμΌμ„ κΉ”λ”ν•˜κ²Œ μœ μ§€ν•  수 μžˆλ‹€.

πŸ”½ 단점

  • μΈν„°νŽ˜μ΄μŠ€κ°€ μƒμˆ˜ 관리 λͺ©μ μœΌλ‘œλ§Œ μ‚¬μš©λ  경우, μ΄λŠ” μƒμˆ˜ μΈν„°νŽ˜μ΄μŠ€ μ•ˆν‹°νŒ¨ν„΄μ— 해당될 수 μžˆλ‹€. μΈν„°νŽ˜μ΄μŠ€λŠ” 주둜 클래슀의 ν–‰μœ„λ₯Ό μ •μ˜ν•˜κΈ° μœ„ν•œ μš©λ„μ΄κΈ° λ•Œλ¬Έμ—, μ˜λ„μ— λ§žμ§€ μ•ŠλŠ” 방식일 수 μžˆλ‹€.
  • μƒμˆ˜λ₯Ό μ‚¬μš©ν•˜λŠ” λͺ¨λ“  ν΄λž˜μŠ€μ—μ„œ implementsλ₯Ό 톡해 μƒμˆ˜ μΈν„°νŽ˜μ΄μŠ€λ₯Ό 상속받아야 ν•˜λ―€λ‘œ, μœ μ—°μ„±μ΄ λ–¨μ–΄μ§ˆ 수 μžˆλ‹€.

 

β–Ά 자체 클래슀 μƒμˆ˜

μƒμˆ˜λ₯Ό λ³„λ„μ˜ 클래슀둜 λΆ„λ¦¬ν•˜μ—¬ κ΄€λ¦¬ν•˜λŠ” 방식이닀. κΈ°λŠ₯λ³„λ‘œ μƒμˆ˜ 클래슀λ₯Ό λ§Œλ“€μ–΄ κ·Έλ£Ήν™”ν•˜λ©°, 주둜 Utility Class ν˜•νƒœλ‘œ μ‚¬μš©λœλ‹€. μΈμŠ€ν„΄μŠ€ 생성을 λ°©μ§€ν•˜κΈ° μœ„ν•΄ private μƒμ„±μžλ₯Ό 두고, λͺ¨λ“  μƒμˆ˜λ₯Ό public static final둜 μ„ μ–Έν•œλ‹€.

πŸ”½ 2μ£Όμ°¨ 과제(μžλ™μ°¨ κ²½μ£Ό): 자체 클래슀 μƒμˆ˜

public class CarConstants {
    public static final int MOVE_THRESHOLD = 4;
    public static final int RANDOM_MIN = 0;
    public static final int RANDOM_MAX = 9;
    public static final int MOVE_INCREMENT = 1;

    private CarConstants() {
    }
}

πŸ”½ μž₯점

  • μƒμˆ˜λ₯Ό κΈ°λŠ₯λ³„λ‘œ 뢄리해 관리할 수 μžˆμ–΄ μ½”λ“œκ°€ κΉ”λ”ν•˜κ³  가독성이 λ†’μ•„μ§„λ‹€.
  • 객체 생성 없이 접근이 κ°€λŠ₯ν•˜μ—¬ λ©”λͺ¨λ¦¬ μ‚¬μš©μ΄ νš¨μœ¨μ μ΄λ‹€.
  • μƒμˆ˜μ— λŒ€ν•œ λͺ¨λ“ˆν™”κ°€ μš©μ΄ν•˜μ—¬ μ½”λ“œ μœ μ§€λ³΄μˆ˜κ°€ 쉽닀.

πŸ”½ 단점

  • 단일 κ°’λ§Œ 담을 수 μžˆμ–΄, 볡합적인 μƒμˆ˜ 그룹을 효과적으둜 λ‚˜νƒ€λ‚΄κΈ° μ–΄λ ΅λ‹€.

 

 

βœ… Enum의 κΈ°λ³Έ 문법

β–Ά μ„ μ–Έ

  • enum 이름은 ν΄λž˜μŠ€μ™€ λ™μΌν•˜κ²Œ 첫 κΈ€μžλ₯Ό λŒ€λ¬Έμžλ‘œ μ‹œμž‘ν•œλ‹€.
  • κ΄€λ‘€μ μœΌλ‘œ μ—΄κ±° μƒμˆ˜λŠ” λͺ¨λ‘ λŒ€λ¬Έμžλ‘œ μž‘μ„±ν•œλ‹€.
  • μ—΄κ±° μƒμˆ˜κ°€ μ—¬λŸ¬ λ‹¨μ–΄λ‘œ ꡬ성될 경우, 단어 사이λ₯Ό 밑쀄(_)둜 μ—°κ²°ν•œλ‹€.

πŸ”½ 3μ£Όμ°¨ 과제(둜또): 둜또 μˆœμœ„λ₯Ό enum으둜 ν™œμš©

public enum Rank {
    FIRST_PLACE,
    SECOND_PLACE,
    THIRD_PLACE,
    FOURTH_PLACE,
    FIFTH_PLACE,
    LAST_PLACE
}

 

β–Ά λ©”μ„œλ“œ μ’…λ₯˜

λ©”μ„œλ“œ μ„€λͺ… λ°˜ν™˜ νƒ€μž…
name() μ—΄κ±° 객체의 λ¬Έμžμ—΄μ„ λ°˜ν™˜ String
ordinal() μ—΄κ±° 객체의 순번(0λΆ€ν„° μ‹œμž‘)을 λ°˜ν™˜ int
valueOf(String name) λ¬Έμžμ—΄μ„ μž…λ ₯λ°›μ•„μ„œ μΌμΉ˜ν•˜λŠ” μ—΄κ±° 객체λ₯Ό λ°˜ν™˜ enum
values() λͺ¨λ“  μ—΄κ±° 객체듀을 λ°°μ—΄λ‘œ λ°˜ν™˜ enum[]
compareTo() μ—΄κ±° 객체 κ°„ 순번 차이λ₯Ό λΉ„κ΅ν•˜μ—¬ λ°˜ν™˜ int
equals() μ—΄κ±° 객체와 λ‹€λ₯Έ 객체λ₯Ό λΉ„κ΅ν•˜μ—¬ 일치 μ—¬λΆ€λ₯Ό λ°˜ν™˜ boolean

πŸ”½ name()

μ—΄κ±° 객체가 κ°€μ§€κ³  μžˆλŠ” λ¬Έμžμ—΄μ„ λ°˜ν™˜ν•œλ‹€.

Rank rank = Rank.SECOND_PLACE;
String rankName = rank.name();
System.out.println(rankName); // SECOND_PLACE

πŸ”½ ordinal()

μ—΄κ±° 객체의 순번(0λΆ€ν„° μ‹œμž‘)을 λ°˜ν™˜ν•œλ‹€.

Rank rank = Rank.SECOND_PLACE;
int rankNum = rank.ordinal();
System.out.println(rankNum); // 2

πŸ”½ valueOf()

λ¬Έμžμ—΄μ„ μž…λ ₯λ°›μ•„ μΌμΉ˜ν•˜λŠ” μ—΄κ±° 객체λ₯Ό λ°˜ν™˜ν•œλ‹€.

Rank rank = Rank.valueOf("SECOND_PLACE");
System.out.println(rank); // SECOND_PLCAE

πŸ”½ values()

λͺ¨λ“  μ—΄κ±° 객체듀을 λ°°μ—΄λ‘œ λ°˜ν™˜ν•œλ‹€.

Rank[] ranks = Rank.values();
System.out.println(Arrays.toString(ranks)); // [FIRST_PLACE, SECOND_PLACE, THIRD_PLACE, FOURTH_PLACE, FIFTH_PLACE, LAST_PLACE]

πŸ”½ compareTo()

μ£Όμ–΄μ§„ μ—΄κ±° 객체λ₯Ό λΉ„κ΅ν•΄μ„œ 순번 차이λ₯Ό λ°˜ν™˜ν•œλ‹€.

  • μ—΄κ±° 객체가 맀개 λ³€μˆ˜μ˜ μ—΄κ±° 객체보닀 순번이 λΉ λ₯΄λ©΄ 음수λ₯Ό λ°˜ν™˜ν•œλ‹€.
  • μ—΄κ±° 객체가 맀개 λ³€μˆ˜μ˜ μ—΄κ±° 객체보닀 순번이 늦으면 μ–‘μˆ˜λ₯Ό λ°˜ν™˜ν•œλ‹€.
Rank firstRank = Rank.FIRST_PLACE;
Rank secondRank = Rank.SECOND_PLACE;

int firstCompare = firstRank.compareTo(secondRank);
System.out.println(firstCompare); // -1

int secondCompare = secondRank.compareTo(firstRank);
System.out.println(secondCompare); // 1

πŸ”½ equals()

ν•΄λ‹Ή enum μƒμˆ˜μ™€ λ‹€λ₯Έ 객체λ₯Ό λΉ„κ΅ν•˜μ—¬ boolean ν˜•νƒœλ‘œ λ°˜ν™˜ν•œλ‹€.

Rank firstRank = Rank.FIRST_PLACE;
Rank secondRank = Rank.SECOND_PLACE;

boolean isEqual = firstRank.equals(secondRank);
System.out.println(isEqual); // false

 

 

βœ… Enum κ³ κΈ‰ 문법

β–Ά λ§€ν•‘

enum을 ν™œμš©ν•˜λ©΄ νŠΉμ • κ°’κ³Ό λ§€ν•‘λœ μ—΄κ±° μƒμˆ˜λ₯Ό 좜λ ₯ν•  수 μžˆλ‹€. enum의 μƒμ„±μžμ— λ§€κ°œλ³€μˆ˜λ₯Ό 전달해 각 μ—΄κ±° 객체에 κ³ μœ ν•œ 값을 λΆ€μ—¬ν•  수 있으며, 이λ₯Ό ν•„λ“œμ— μ €μž₯ν•œλ‹€. μ΄λ ‡κ²Œ μ €μž₯된 ν•„λ“œλŠ” getter λ©”μ„œλ“œλ₯Ό 톡해 μ ‘κ·Όν•  수 μžˆμ–΄, μ—΄κ±° 객체와 μ—°κ΄€λœ 정보λ₯Ό κ°€μ Έμ˜¬ 수 μžˆλ‹€.

πŸ”½ 3μ£Όμ°¨ 과제(둜또): Enum 맀핑을 ν™œμš©ν•œ Rank 객체

public enum Rank {
    FIRST_PLACE(6, false, 2000000000),
    SECOND_PLACE(5, true, 30000000),
    THIRD_PLACE(5, false, 1500000),
    FOURTH_PLACE(4, false, 50000),
    FIFTH_PLACE(3, false, 5000),
    LAST_PLACE(0, false, 0)
    ;

    // ν•„λ“œ
    private final Integer matchCount;
    private final boolean requireBonusNumberMatch;
    private final Integer prizeAmount;

    // μƒμ„±μž
    Rank(Integer matchCount, boolean requireBonusNumberMatch, Integer prizeAmount) {
        this.matchCount = matchCount;
        this.requireBonusNumberMatch = requireBonusNumberMatch;
        this.prizeAmount = prizeAmount;
    }

    // Getter (일치 개수)
    public Integer getMatchCount() {
        return matchCount;
    }

    // Getter (λ³΄λ„ˆμŠ€ 번호 일치 μ—¬λΆ€)
    private boolean isRequireBonusNumberMatch() {
        return requireBonusNumberMatch;
    }

    // Getter (μƒκΈˆ)
    public Integer getPrizeAmount() {
        return prizeAmount;
    }
    
    ...
    
}

 

 

βœ… Enum의 νŠΉμ§•

  • κΈ°λ³Έ μžλ£Œν˜•(primitive)이 μ•„λ‹Œ μ°Έμ‘°(reference) νƒ€μž…μ΄λ‹€.
    • μ°Έμ‘° νƒ€μž…μ΄λ―€λ‘œ null도 μ €μž₯이 κ°€λŠ₯ν•˜λ‹€.
    • == μ—°μ‚°μž 비ꡐ μ‹œ trueλ₯Ό λ°˜ν™˜ν•œλ‹€.
  • 상속을 μ§€μ›ν•˜μ§€ μ•ŠλŠ”λ‹€.
    • λͺ¨λ“  enum듀은 λ‚΄λΆ€μ μœΌλ‘œ java.lang.enum 클래슀λ₯Ό 상속받고 μžˆλ‹€. μžλ°”λŠ” 닀쀑 상속을 μ§€μ›ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ—, λ‹€λ₯Έ 클래슀λ₯Ό 상속받을 수 μ—†λ‹€.
  • Enum ν΄λž˜μŠ€λŠ” Object 클래슀의 λ‹€μŒ λ„€ κ°€μ§€ λ©”μ„œλ“œλ₯Ό μ˜€λ²„λΌμ΄λ”©ν•  수 없도둝 final둜 μ„ μ–Έν•΄ λ³€κ²½ν•˜μ§€ λͺ»ν•˜λ„둝 λ§‰μ•„λ†“μ•˜λ‹€. μƒμˆ˜λ₯Ό κ³ μœ ν•˜κ²Œ μœ μ§€ν•˜κΈ° μœ„ν•œ λͺ©μ μ΄λ‹€.
λ©”μ„œλ“œ μ„€λͺ…
clone() 객체λ₯Ό λ³΅μ œν•˜λŠ” λ©”μ„œλ“œ
finalize() Garbage Collection이 λ°œμƒν•  λ•Œ μ²˜λ¦¬ν•˜κΈ° μœ„ν•œ λ©”μ„œλ“œ
hashCode() int νƒ€μž…μ˜ ν•΄μ‹œ μ½”λ“œ 값을 λ°˜ν™˜ν•˜λŠ” λ©”μ„œλ“œ
equals() 두 개의 객체가 λ™μΌν•œμ§€ ν™•μΈν•˜λŠ” λ©”μ„œλ“œ

 

 

βœ… Enum의 μž₯점 ⭐️⭐️⭐️

πŸ”½ 기본적인 μž₯점

  • μ½”λ“œκ°€ λ‹¨μˆœν•΄μ§€κ³  가독성이 μ’‹μ•„μ§„λ‹€.
  • IDE의 적극적인 지원을 받을 수 μžˆλ‹€. (μžλ™ μ™„μ„±, μ˜€νƒ€ 검증, ν…μŠ€νŠΈ λ¦¬νŒ©ν† λ§ λ“±)
  • λ¦¬νŒ©ν† λ§ μ‹œ μˆ˜μ • λ²”μœ„κ°€ μ΅œμ†Œν™”λœλ‹€. Enum에 λ‚΄μš©μ΄ μΆ”κ°€λ˜λ”λΌλ„ λ‹€λ₯Έ μ½”λ“œ μˆ˜μ •μ΄ ν•„μš”ν•˜μ§€ μ•Šλ‹€.
  • νŠΉμ • μ—΄κ±°ν˜• κ°’λ§Œμ„ λ³€μˆ˜μ— ν• λ‹Ήν•  수 μžˆμ–΄, 컴파일 λ‹¨κ³„μ—μ„œ νƒ€μž… μ•ˆμ •μ„±μ„ 보μž₯받을 수 μžˆλ‹€.
  • μ—΄κ±°ν˜• μƒμˆ˜λΏλ§Œ μ•„λ‹ˆλΌ μƒμ„±μž, λ©”μ„œλ“œ, ν•„λ“œλ₯Ό κ°€μ§ˆ 수 μžˆμ–΄ 객체지ν–₯적으둜 섀계할 수 μžˆλ‹€.

μ΄λŸ¬ν•œ 기본적인 μž₯점 외에도 이번 과제λ₯Ό ν•˜λ©° 느꼈던 Enum의 핡심 μž₯점은 λ‹€μŒκ³Ό κ°™λ‹€.

 

β–Ά μƒνƒœμ™€ ν–‰μœ„λ₯Ό ν•œ κ³³μ—μ„œ 관리

이번 κ³Όμ œμ—μ„œ 둜또 당첨 λ²ˆν˜Έμ™€ λ§€μΉ­ 횟수, λ³΄λ„ˆμŠ€ 번호 일치 μ—¬λΆ€λ₯Ό 톡해 각 λ“±μˆ˜λ₯Ό νŒλ³„ν•˜λŠ” 둜직이 ν•„μš”ν–ˆλ‹€. μ΄λ•Œ, μƒμˆ˜λ§ˆλ‹€ λ‹€λ₯Έ λ™μž‘μ΄ ν•„μš”ν•˜λ‹€λ©΄ 보톡 if-elseλ‚˜ switch문을 톡해 각각의 쑰건을 λΆ„κΈ°ν•˜μ—¬ μ²˜λ¦¬ν•˜λŠ” 것이 μΌλ°˜μ μ΄λ‹€.

πŸ”½ 3μ£Όμ°¨ 과제(둜또): λ³€κ²½ μ „ (if-else 방식)

ν•˜μ§€λ§Œ, ν”„λ‘œκ·Έλž˜λ° μš”κ΅¬μ‚¬ν•­μ— λ”°λ₯΄λ©΄ else 및 switch문을 μ‚¬μš©ν•˜μ§€ λ§λΌλŠ” 지침이 μžˆμ—ˆλ‹€. ν•΄λ‹Ή 지침이 μƒκ²¨λ‚œ 이유λ₯Ό 생각해보면, 이런 μ‹μ˜ μ½”λ“œ ꡬ성 방식은 κ°’(μƒνƒœ)κ³Ό λ©”μ„œλ“œ(ν–‰μœ„)의 관계λ₯Ό μ΄ν•΄ν•˜λŠ” 데 μ‹œκ°„μ΄ κ±Έλ¦°λ‹€λŠ” λ¬Έμ œκ°€ μžˆλ‹€. λ˜ν•œ, μƒˆλ‘œμš΄ 쑰건이 좔가될 λ•Œλ§ˆλ‹€ λΆˆν•„μš”ν•˜κ²Œ 뢄기문이 λŠ˜μ–΄λ‚˜ μ½”λ“œμ˜ λ³΅μž‘μ„±μ΄ 증가할 수 μžˆλ‹€λŠ” 단점도 μžˆλ‹€.

public class LottoService {

    public Rank evaluateRank(int matchCount, boolean isBonusNumberMatched) {
        if (matchCount == 6) {
            return Rank.FIRST_PLACE;
        } else if (matchCount == 5 && isBonusNumberMatched) {
            return Rank.SECOND_PLACE;
        } else if (matchCount == 5) {
            return Rank.THIRD_PLACE;
        } else if (matchCount == 4) {
            return Rank.FOURTH_PLACE;
        } else if (matchCount == 3) {
            return Rank.FIFTH_PLACE;
        } else {
            return Rank.LAST_PLACE;
        }
    }
}

πŸ”½ 3μ£Όμ°¨ 과제(둜또): λ³€κ²½ ν›„ (enum ν™œμš©)

Enum을 μ‚¬μš©ν•˜μ—¬ μƒνƒœ(λ§€μΉ­ 횟수, λ³΄λ„ˆμŠ€ 번호 ν•„μš” μ—¬λΆ€, μƒκΈˆ)와 ν–‰μœ„(λ“±μˆ˜ νŒλ³„ 둜직)λ₯Ό ν•œ 곳에 κ²°ν•©ν•˜μ—¬ κ΅¬ν˜„ν–ˆλ‹€.

public enum Rank {
    FIRST_PLACE(6, false, 2000000000),
    SECOND_PLACE(5, true, 30000000),
    THIRD_PLACE(5, false, 1500000),
    FOURTH_PLACE(4, false, 50000),
    FIFTH_PLACE(3, false, 5000),
    LAST_PLACE(0, false, 0)
    ;

    ...

    public static Rank getRankByMatch(Integer matchCount, boolean isBonusNumberMatched) {
        for (Rank rank : Rank.values()) {
            if (isRankMatched(rank, matchCount, isBonusNumberMatched)) {
                return rank;
            }
        }
        return LAST_PLACE;
    }

    private static boolean isRankMatched(Rank rank, Integer matchCount, boolean isBonusNumberMatched) {
        if (rank.isRequireBonusNumberMatch()) {
            return rank.getMatchCount().equals(matchCount) && isBonusNumberMatched;
        }
        return rank.getMatchCount().equals(matchCount);
    }
}

πŸ”½ μž₯점

  • Rank enum 내뢀에 μƒνƒœ(ν•„λ“œ)와 ν–‰μœ„(λ©”μ„œλ“œ)λ₯Ό ν•¨κ»˜ κ΄€λ¦¬ν•˜λ―€λ‘œ μ½”λ“œμ˜ 가독성이 크게 ν–₯μƒλœλ‹€.
  • if-elseλ‚˜ switch문을 λŒ€μ²΄ν•˜μ—¬, enum μƒμˆ˜λ§ˆλ‹€ ν•„μš”ν•œ μƒνƒœμ™€ λ©”μ„œλ“œλ₯Ό μž‘μ„±ν•¨μœΌλ‘œμ¨ μ€‘λ³΅λ˜λŠ” 뢄기문을 μ œκ±°ν•  수 μžˆλ‹€.
  • Rank enum에 좔가적인 λ‘œμ§μ„ λ„£μ–΄μ•Ό ν•  λ•Œ, λ‹€λ₯Έ 클래슀의 μ½”λ“œλ₯Ό κ±΄λ“œλ¦¬μ§€ μ•Šκ³  enumμ—λ§Œ μΆ”κ°€ν•˜λ©΄ λ˜μ–΄ μœ μ§€λ³΄μˆ˜κ°€ μ‰¬μ›Œμ§„λ‹€.

 

β–Ά Thread-safe인 싱글톀 객체

enum μžμ²΄κ°€ 싱글톀 νŒ¨ν„΄μ€ μ•„λ‹ˆμ§€λ§Œ, 각 μ—΄κ±° μƒμˆ˜λŠ” 싱글톀 객체둜 μ·¨κΈ‰λœλ‹€. enum에 μ •μ˜λœ 각 μƒμˆ˜λŠ” ν•œ 번만 μ΄ˆκΈ°ν™”λ˜κ³  JVM이 μ’…λ£Œλ  λ•ŒκΉŒμ§€ κ³ μœ ν•œ μΈμŠ€ν„΄μŠ€λ‘œ μœ μ§€λœλ‹€. λ”°λΌμ„œ enum의 μ—΄κ±°ν˜• μƒμˆ˜λŠ” κ³ μœ ν•œ μΈμŠ€ν„΄μŠ€λ‘œ, 싱글톀 νŒ¨ν„΄κ³Ό μœ μ‚¬ν•œ νŠΉμ§•μ„ μ§€λ‹ˆλ©°, 특히 enum은 thread-safeν•˜μ—¬ μ•ˆμ „ν•˜κ²Œ μ‚¬μš©ν•  수 μžˆλŠ” μž₯점이 μžˆλ‹€.

πŸ”½ 3μ£Όμ°¨ 과제(둜또): Enum Rank 객체

public enum Rank {
    FIRST_PLACE(6, false, 2000000000),
    SECOND_PLACE(5, true, 30000000),
    THIRD_PLACE(5, false, 1500000),
    FOURTH_PLACE(4, false, 50000),
    FIFTH_PLACE(3, false, 5000),
    LAST_PLACE(0, false, 0)
    ;

    // ν•„λ“œ
    private final Integer matchCount;
    private final boolean requireBonusNumberMatch;
    private final Integer prizeAmount;

    // μƒμ„±μž
    Rank(Integer matchCount, boolean requireBonusNumberMatch, Integer prizeAmount) {
        this.matchCount = matchCount;
        this.requireBonusNumberMatch = requireBonusNumberMatch;
        this.prizeAmount = prizeAmount;
    }
    
    ...
    
}

πŸ”½ 3μ£Όμ°¨ 과제(둜또): Application의 main λ©”μ„œλ“œ

public class Application {
    public static void main(String[] args) {
        Rank firstInstance = Rank.FIRST_PLACE;
        Rank secondInstance = Rank.FIRST_PLACE;

        // λ™μΌν•œ μΈμŠ€ν„΄μŠ€μΈμ§€ 비ꡐ
        if (firstInstance == secondInstance) {
            System.out.println("Rank.FIRST_PLACEλŠ” μ‹±κΈ€ν†€μž…λ‹ˆλ‹€!");
        } else {
            System.out.println("Rank.FIRST_PLACEλŠ” 싱글톀이 μ•„λ‹™λ‹ˆλ‹€.");
        }
    }
}

πŸ”½ 3μ£Όμ°¨ 과제(둜또): 좜λ ₯ κ²°κ³Ό

Rank.FIRST_PLACEλŠ” μ‹±κΈ€ν†€μž…λ‹ˆλ‹€!

 

싱글톀 νŒ¨ν„΄μ˜ 핡심은 μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ „μ—­μ—μ„œ 단 ν•˜λ‚˜μ˜ μΈμŠ€ν„΄μŠ€λ§Œ μƒμ„±ν•˜κ³ , κ·Έ μΈμŠ€ν„΄μŠ€λ₯Ό μ—¬λŸ¬ κ³³μ—μ„œ κ³΅μœ ν•˜λ„λ‘ ν•˜λŠ” 것이닀. μ΄λ ‡κ²Œ 되면 λ©”λͺ¨λ¦¬ μ‚¬μš©μ΄ 효율적이며, νŠΉμ • μƒνƒœλ‚˜ 섀정을 μΌκ΄€λ˜κ²Œ μœ μ§€ν•  수 μžˆλŠ” μž₯점이 μžˆλ‹€.
κ·ΈλŸ¬λ‚˜ 싱글톀 μΈμŠ€ν„΄μŠ€λ₯Ό λ©€ν‹°μŠ€λ ˆλ“œ ν™˜κ²½μ—μ„œ μ•ˆμ „ν•˜κ²Œ κ³΅μœ ν•˜λ €λ©΄ thread-safeν•΄μ•Ό ν•œλ‹€. λ§Œμ•½ μ—¬λŸ¬ μŠ€λ ˆλ“œκ°€ λ™μ‹œμ— μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜λ € μ‹œλ„ν•œλ‹€λ©΄, 싱글톀 νŒ¨ν„΄μ˜ μ˜λ„μ™€ 달리 μΈμŠ€ν„΄μŠ€κ°€ μ—¬λŸ¬ 개 μƒμ„±λ˜λŠ” 상황이 λ°œμƒν•  수 μžˆλ‹€. thread-safeν•œ 싱글톀 κ΅¬ν˜„μ€ 이런 문제λ₯Ό λ°©μ§€ν•˜μ—¬ μ—¬λŸ¬ μŠ€λ ˆλ“œκ°€ λ™μ‹œμ— 접근해도 λ™μΌν•œ μΈμŠ€ν„΄μŠ€λ§Œ μ‚¬μš©ν•˜λ„λ‘ 보μž₯ν•œλ‹€.

 

 

πŸ“ μ°Έκ³  자료