#design-pattern

μƒνƒœ νŒ¨ν„΄(State Pattern)을 μ‚¬μš©ν•΄λ³΄μž

μƒνƒœ νŒ¨ν„΄(State Pattern)을 μ‚¬μš©ν•΄λ³΄μž
(자료 좜처 : https://view.genial.ly/5eb18d77e4d83e0d37f2aa38/presentation-emociones-en-adolescentes)

πŸ₯° 😁 😐 😩 🀬 😴

μƒνƒœ(ν˜„μž¬ 진행쀑인 ν–‰μœ„)λ₯Ό λ‚˜νƒ€λ‚΄κΈ° μœ„ν•΄ μ–΄λ–€ 방식을 μ‚¬μš©ν•΄ μ™”λŠ”κ°€?

Enum

μ—΄κ±°ν˜•(Enum) μ΄λž€ μ„œλ‘œ μ—°κ΄€λœ μƒμˆ˜λ“€μ˜ 집합이닀. μƒνƒœλ₯Ό λ‚˜νƒ€λ‚΄κΈ°μ—λŠ” 정말 νŽΈλ¦¬ν•œ 방식이라고 μƒκ°ν•œλ‹€. ν•˜μ§€λ§Œ Enum 은 객체 지ν–₯적인 ν”„λ‘œκ·Έλž˜λ°μ΄λΌκ³  ν•˜κΈ° μ• λ§€ν•œ 뢀뢄이 μžˆλ‹€. κ·Έ 뢀뢄에 λŒ€ν•΄μ„œλŠ” 쑰금 μžˆλ‹€κ°€ μ•Œμ•„λ³΄μž.

μƒνƒœ νŒ¨ν„΄

β€œνŠΉμ • κΈ°λŠ₯을 μˆ˜ν–‰ν•œ ν›„ λ‹€μŒ μƒνƒœλ₯Ό λ°˜ν™˜ν•˜λŠ” 것”

μƒνƒœ νŒ¨ν„΄μ€ μƒνƒœκ°€ λ§Žμ•„μ§€λ”λΌλ„ μ½”λ“œμ˜ λ³΅μž‘λ„κ°€ μ¦κ°€ν•˜μ§€ μ•Šμ§€λ§Œ enum μ—μ„œ 쑰건문을 μ΄μš©ν•œ 방식은 μ½”λ“œλ₯Ό λ³΅μž‘ν•˜κ²Œ λ§Œλ“€μ–΄ μœ μ§€ 보수λ₯Ό μ–΄λ ΅κ²Œ ν•œλ‹€.

μƒνƒœ νŒ¨ν„΄ 적용

λ™μΌν•œ λ©”μ„œλ“œκ°€ μƒνƒœμ— 따라 λ‹€λ₯΄κ²Œ λ™μž‘ν•  λ•Œ μ‚¬μš©ν•  수 μžˆλŠ” νŒ¨ν„΄μ΄ μƒνƒœ νŒ¨ν„΄(State Pattern)이닀. μƒνƒœ νŒ¨ν„΄μ—μ„œλŠ” μƒνƒœλ₯Ό λ³„λ„μ˜ νƒ€μž…μœΌλ‘œ λΆ„λ¦¬ν•˜κ³  μƒνƒœλ³„λ‘œ μ•Œλ§žμ€ ν•˜μœ„ νƒ€μž…μ„ κ΅¬ν˜„ν•œλ‹€. μƒνƒœ νŒ¨ν„΄μ— λŒ€ν•΄ μ•Œκ²Œ λ˜μ—ˆμœΌλ‹ˆ μ‹€μ œλ‘œ μƒνƒœ νŒ¨ν„΄μ„ μ‚¬μš©ν•΄λ³΄μž.

백견이 λΆˆμ—¬μΌν–‰(η™Ύθ¦‹θ€Œ δΈε¦‚δΈ€θ‘Œ)

μƒνƒœνŒ¨ν„΄μ„ μ‚¬μš©ν•΄λ³΄κΈ° μœ„ν•œ κ°„λ‹¨ν•œ 예제 ν”„λ‘œκ·Έλž¨μ„ λ§Œλ“€μ–΄ λ³Έλ‹€. μ˜ˆμ‹œμ— μ‚¬μš©λ  ν”„λ‘œκ·Έλž¨μ€ μ‚¬λžŒμ˜ 감정 μƒνƒœλ₯Ό λ³€κ²½ν•˜λŠ” κ°„λ‹¨ν•œ μ˜ˆμ‹œ ν”„λ‘œκ·Έλž¨μ΄λ‹€.

κ΅¬ν˜„ν•  수 μžˆλŠ” κΈ°λŠ₯에 λŒ€ν•œ μ˜ˆμ‹œλ₯Ό μ£Όμ„μœΌλ‘œ μ μ—ˆλ‹€. μƒνƒœ νŒ¨ν„΄μ€ μΆ”μƒν™”λœ λ™μΌν•œ λ©”μ„œλ“œμ— μƒνƒœλ§ˆλ‹€ λ‹€λ₯Έ νŠΉμ • κΈ°λŠ₯을 μˆ˜ν–‰ν•œ ν›„ λ‹€μŒ μƒνƒœλ₯Ό λ°˜ν™˜ν•˜λŠ” 것이 μƒνƒœ νŒ¨ν„΄μ˜ 핡심이라고 λ³Ό 수 μžˆλ‹€.

@Override
public State μ–΄λ–€_ν–‰μœ„() {
	ν˜„μž¬ μƒνƒœμ— λŒ€ν•΄μ„œ μ–΄λ–€ ν–‰μœ„κ°€ λ°œμƒν–ˆμ„ λ•Œμ˜ 상황을 μ²˜λ¦¬ν•œλ‹€.
	μ²˜λ¦¬κ°€ λλ‚œ ν›„ λ³€ν™”λœ μƒνƒœλ₯Ό λ°˜ν™˜ν•œλ‹€.
}

State Interface

κ΅¬ν˜„ν•  μƒνƒœμ— λ³€ν™”λ₯Ό 쀄 κΈ°λŠ₯을 μΆ”μƒν™”ν•œλ‹€. ν•΄λ‹Ή κΈ°λŠ₯은 λ‹¨μˆœν•˜κ²Œ 둜또 당첨이 λ˜μ—ˆμ„ λ•Œ, λˆμ„ λ²Œμ—ˆμ„ λ•Œ, λˆμ„ μžƒμ—ˆμ„ λ•Œ, λ‹Ήμ²¨λœ 둜또λ₯Ό μžƒμ–΄λ²„λ Έμ„ λ•Œλ₯Ό 좔상화해두고 μƒνƒœμ— 맞게 κ΅¬ν˜„ν•˜λ„λ‘ λ˜μ–΄ μžˆλ‹€.

public interface State {
    State winLottery();

    State earnMoney();

    State loseMoney();

    State loseWinLottery();

    void printCurrentEmotion();
}

Emotion

λ‘œλ˜κ°€ λ‹Ήμ²¨λ˜κ±°λ‚˜ λ‹Ήμ²¨λœ 둜또λ₯Ό μžƒμ–΄λ²„λ¦° κ²½μš°λŠ” μ–΄λ– ν•œ μƒνƒœμ—μ„œλ„ μ΅œμƒμ˜ κΈ°λΆ„κ³Ό μ΅œμ•…μ˜ κΈ°λΆ„μ˜ μƒνƒœλ‘œ λ³€κ²½μ‹œν‚¨λ‹€κ³  μƒκ°ν•˜κ³ , μ€‘λ³΅λ˜λŠ” κΈ°λŠ₯μ΄λ―€λ‘œ 좔상 클래슀둜 κ΅¬ν˜„ν•œλ‹€. μ΄λ ‡κ²Œ λ§Œλ“€μ–΄μ§„ 좔상 클래슀λ₯Ό 상속받아 각각의 μƒνƒœλ₯Ό κ΅¬ν˜„ν•œλ‹€. 이후에 μ†Œμœ ν•œ λˆμ— 따라 기뢄이 λ‹¬λΌμ§€λŠ” κΈ°λŠ₯처럼 μƒνƒœκ°€ ν•„μš”ν•œ 경우 ν•΄λ‹Ή 좔상 ν΄λž˜μŠ€μ— μƒνƒœλ₯Ό μΆ”κ°€ν•˜μ—¬ κ΅¬ν˜„ν•  수 μžˆκ² λ‹€.

public abstract class Emotion implements State {
    @Override // 둜또 당첨은 기뢄이 μ΅œμƒμ΄ λ©λ‹ˆλ‹€.
    public State winLottery() {
        return new Perfect();
    }

    @Override // λ‹Ήμ²¨λœ 둜또λ₯Ό μžƒμ–΄λ²„λ¦¬λ©΄ 기뢄이 μ΅œμ•…μ΄ λ©λ‹ˆλ‹€.
    public State loseWinLottery() {
        return new Terrible();
    }
}

Perfect

μ΅œμƒμ˜ κΈ°λΆ„ μƒνƒœλ₯Ό ν‘œν˜„ν•˜λŠ” 클래슀λ₯Ό λ§Œλ“ λ‹€.

public class Perfect extends Emotion {
    @Override // 기뢄이 λ³€κ²½λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
    public State earnMoney() {
        // 기뢄이 더 μ’‹μ•„μ§ˆ 수 μ—†κΈ° λ•Œλ¬Έμ— μ˜ˆμ™Έλ₯Ό λ°œμƒμ‹œν‚€λŠ” 방식을 μ‚¬μš©ν•  μˆ˜λ„ μžˆλ‹€.
        return this;
    }

    @Override // λˆμ„ μžƒμ–΄μ„œ ν•œ 단계 기뢄이 λ‚˜λΉ μ§‘λ‹ˆλ‹€.
    public State loseMoney() {
        return new Happy();
    }

    @Override
    public void printCurrentEmotion() {
        System.out.println("μ΅œκ³ μž…λ‹ˆλ‹€.");
    }
}

Happy

기뢄이 쒋은 μƒνƒœλ₯Ό ν‘œν˜„ν•˜λŠ” 클래슀λ₯Ό λ§Œλ“ λ‹€.

public class Happy extends Emotion {
    @Override // λˆμ„ λ²Œμ–΄μ„œ ν•œ 단계 기뢄이 μ’‹μ•„μ§‘λ‹ˆλ‹€.
    public State earnMoney() {
      	// 예) 기뢄이 λ„ˆλ¬΄ μ’‹μ•„μ„œ μ£Όλ³€ 지인듀과 νŒŒν‹°λ₯Ό ν•˜λŠ” κΈ°λŠ₯ 처리
        return new Perfect();
    }

    @Override // λˆμ„ μžƒμ–΄μ„œ ν•œ 단계 기뢄이 λ‚˜λΉ μ§‘λ‹ˆλ‹€.
    public State loseMoney() {
        return new SoSo();
    }

    @Override
    public void printCurrentEmotion() {
        System.out.println("ν–‰λ³΅ν•©λ‹ˆλ‹€.");
    }
}

SoSo

보톡 κΈ°λΆ„ μƒνƒœλ₯Ό ν‘œν˜„ν•˜λŠ” 클래슀λ₯Ό λ§Œλ“ λ‹€.

public class SoSo extends Emotion {
    @Override // λˆμ„ λ²Œμ–΄μ„œ ν•œ 단계 기뢄이 μ’‹μ•„μ§‘λ‹ˆλ‹€.
    public State earnMoney() {
        return new Happy();
    }

    @Override // λˆμ„ μžƒμ–΄μ„œ ν•œ 단계 기뢄이 λ‚˜λΉ μ§‘λ‹ˆλ‹€.
    public State loseMoney() {
        return new Bad();
    }

    @Override
    public void printCurrentEmotion() {
        System.out.println("κ·Έμ €κ·Έλž˜μš”.");
    }
}

Bad

λ‚˜μœ κΈ°λΆ„ μƒνƒœλ₯Ό ν‘œν˜„ν•˜λŠ” 클래슀λ₯Ό λ§Œλ“ λ‹€.

public class Bad extends Emotion {
    @Override // λˆμ„ λ²Œμ–΄μ„œ ν•œ 단계 기뢄이 μ’‹μ•„μ§‘λ‹ˆλ‹€.
    public State earnMoney() {
        return new SoSo();
    }

    @Override // λˆμ„ μžƒμ–΄μ„œ ν•œ 단계 기뢄이 λ‚˜λΉ μ§‘λ‹ˆλ‹€.
    public State loseMoney() {
      	// 예) 기뢄이 λ„ˆλ¬΄ λ‚˜λΉ μ§€λ©° μΉœν•œ μΉœκ΅¬μ™€ μˆ μ„ λ¨ΉλŠ” κΈ°λŠ₯ 처리
        return new Terrible();
    }

    @Override
    public void printCurrentEmotion() {
        System.out.println("λ³„λ‘œμž…λ‹ˆλ‹€.");
    }
}

Terrible

μ΅œμ•…μ˜ κΈ°λΆ„ μƒνƒœλ₯Ό ν‘œν˜„ν•˜λŠ” 클래슀λ₯Ό λ§Œλ“ λ‹€.

public class Terrible extends Emotion {
    @Override // λˆμ„ λ²Œμ–΄μ„œ ν•œ 단계 기뢄이 μ’‹μ•„μ§‘λ‹ˆλ‹€.
    public State earnMoney() {
        return new Bad();
    }

    @Override // 기뢄이 λ³€κ²½λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
    public State loseMoney() {
        // 기뢄이 더 λ‚˜λΉ μ§ˆ 수 μ—†κΈ° λ•Œλ¬Έμ— μ˜ˆμ™Έλ₯Ό λ°œμƒμ‹œν‚€λŠ” 방식을 μ‚¬μš©ν•  μˆ˜λ„ μžˆλ‹€.
        return this;
    }

    @Override
    public void printCurrentEmotion() {
        System.out.println("μ΅œμ•…μž…λ‹ˆλ‹€.");
    }
}

κΈ°λŠ₯ 적용

Person

μœ„μ—μ„œ ν…ŒμŠ€νŠΈκ°€ μ •μƒμ μœΌλ‘œ ν†΅κ³Όλ˜μ—ˆλ‹€λ©΄ μ‹€μ œλ‘œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ μ‹€ν–‰ν•΄ 보도둝 ν•˜μž. λ§Œλ“€μ–΄λ‘” 감정 μƒνƒœλ₯Ό 가지고 μžˆλŠ” Person 을 λ§Œλ“ λ‹€. Person μ—μ„œ κ΅¬ν˜„ν•œ κΈ°λŠ₯듀은 호좜이 되면 μƒνƒœκ°€ λ³€κ²½λ˜κ³  λ³€κ²½λœ μƒνƒœλ₯Ό 좜λ ₯ν•΄μ£ΌλŠ” κ°„λ‹¨ν•œ κΈ°λŠ₯이 κ΅¬ν˜„λ˜μ–΄μžˆλ‹€.

public class Person {
    private State state;

    public Person(State state) {
        this.state = state;
    }

    public void winLottery() {
        state = state.winLottery();
        state.printCurrentEmotion();
    }

    public void earnMoney() {
        state = state.earnMoney();
        state.printCurrentEmotion();
    }

    public void loseMoney() {
        state = state.loseMoney();
        state.printCurrentEmotion();
    }

    public void printCurrentEmotion() {
        state.printCurrentEmotion();
    }
}

Application

Person μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•œλ‹€. λ©”μ„œλ“œ ν˜ΈμΆœμ— λ”°λΌμ„œ μƒνƒœκ°€ λ³€κ²½λ˜λŠ” λͺ¨μŠ΅μ„ 확인할 수 μžˆλ‹€. μ΄λ ‡κ²Œ μƒνƒœλ₯Ό 객체둜 κ΄€λ¦¬ν•˜κ²Œ 되면 각각의 μƒνƒœλ§ˆλ‹€ 세뢀적인 κΈ°λŠ₯ κ΅¬ν˜„μ„ ν•  수 μžˆλ‹€.

public class Application {
    public static void main(String[] args) {
        Person person = new Person(new SoSo());
        person.printCurrentEmotion();
        person.earnMoney();
        person.winLottery();
        person.loseMoney();
        person.loseMoney();
        person.loseMoney();
        person.loseMoney();
    }
}

/* μ‹€ν–‰ κ²°κ³Ό
> Task :Application.main()
κ·Έμ € κ·Έλž˜μš”.
행볡 ν•©λ‹ˆλ‹€.
졜고 μž…λ‹ˆλ‹€.
행볡 ν•©λ‹ˆλ‹€.
κ·Έμ € κ·Έλž˜μš”.
λ³„λ‘œ μž…λ‹ˆλ‹€.
μ΅œμ•… μž…λ‹ˆλ‹€. */

μƒˆλ‘œμš΄ 감정 μƒνƒœκ°€ μΆ”κ°€λœλ‹€λ©΄?

μž‘μ€ λ³€ν™”μ—λŠ” 크게 감정 λ³€ν™”κ°€ 생기지 μ•ŠλŠ” μƒνƒœμΈ Sleepy λΌλŠ” 감정 μƒνƒœκ°€ μΆ”κ°€λœλ‹€κ³  ν•œλ‹€.

Sleepy

public class Sleepy extends Emotion {
    @Override // μ‘Έλ¦° μƒνƒœμ—μ„œλŠ” λˆμ„ 쑰금 μ–»λŠ”λ‹€κ³  ν•΄μ„œ 기뢄이 달라지지 μ•ŠλŠ”λ‹€.
    public State earnMoney() {
        return this;
    }

    @Override // μ‘Έλ¦° μƒνƒœμ—μ„œλŠ” λˆμ„ 쑰금 μžƒλŠ”λ‹€κ³  ν•΄μ„œ 기뢄이 달라지지 μ•ŠλŠ”λ‹€.
    public State loseMoney() {
        return this;
    }

    @Override
    public void printCurrentEmotion() {
        System.out.println("μ‘Έλ¦½λ‹ˆλ‹€.");
    }
}

μœ„μ™€ 같은 μƒˆλ‘œμš΄ μƒνƒœκ°€ μΆ”κ°€λ˜λ”λΌλ„ μ½˜ν…μŠ€νŠΈ μ½”λ“œκ°€ λ°›λŠ” 영ν–₯은 μ΅œμ†Œν™”λœλ‹€.

public class Application {
    public static void main(String[] args) {
        Person person = new Person(new Sleepy());
        person.printCurrentEmotion(); // state = Sleepy.class
        person.earnMoney(); // state = Sleepy.class
        person.winLottery(); // state = Perfect.class
    }
}

κ²½ν—˜ν•΄ λ³΄μ•˜λŠ”κ°€?

μ–΄λ–€κ°€? κ°„λ‹¨ν•œ μ˜ˆμ‹œλ₯Ό λ“€μ–΄μ„œ μƒνƒœνŒ¨ν„΄μ— λŒ€ν•΄μ„œ μ„€λͺ…을 ν–ˆλ‹€.

μƒνƒœνŒ¨ν„΄μ΄λž€ 객체 지ν–₯ λ°©μ‹μœΌλ‘œ μƒνƒœ 기계(ν•œ λ²ˆμ— μ˜€λ‘œμ§€ ν•˜λ‚˜μ˜ μƒνƒœλ§Œμ„ κ°€μ§€κ²Œ 되며, ν˜„μž¬ μƒνƒœ(Current State)λž€ μž„μ˜μ˜ 주어진 μ‹œκ°„μ˜ μƒνƒœλ₯Ό 칭함)λ₯Ό κ΅¬ν˜„ν•˜λŠ” ν–‰μœ„ μ†Œν”„νŠΈμ›¨μ–΄ λ””μžμΈ νŒ¨ν„΄μ΄λ‹€. μƒνƒœ νŒ¨ν„΄μ„ μ΄μš©ν•˜λ©΄ μƒνƒœ νŒ¨ν„΄ μΈν„°νŽ˜μ΄μŠ€μ˜ νŒŒμƒ ν΄λž˜μŠ€λ‘œμ„œ 각각의 μƒνƒœλ₯Ό κ΅¬ν˜„ν•¨μœΌλ‘œμ¨, 또 νŒ¨ν„΄μ˜ λΆ€λͺ¨ν΄λž˜μŠ€μ— μ˜ν•΄ μ •μ˜λ˜λŠ” λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜μ—¬ μƒνƒœ λ³€ν™”λ₯Ό κ΅¬ν˜„ν•¨μœΌλ‘œμ¨ μƒνƒœ 기계λ₯Ό κ΅¬ν˜„ν•œλ‹€. μƒνƒœ νŒ¨ν„΄μ˜ μž₯점은 μƒˆλ‘œμš΄ μƒνƒœκ°€ μΆ”κ°€λ˜λ”λΌλ„ μ½˜ν…μŠ€νŠΈ μ½”λ“œκ°€ λ°›λŠ” 영ν–₯은 μ΅œμ†Œν™”λœλ‹€. 클래슀λ₯Ό μΆ”κ°€ν•˜λ”λΌλ„ 기쑴의 λ©”μ„œλ“œμ˜ μ½”λ“œλŠ” κ·ΈλŒ€λ‘œ μœ μ§€λœλ‹€. λ˜ν•œ μƒνƒœμ— λ”°λ₯Έ λ™μž‘μ„ κ΅¬ν˜„ν•œ μ½”λ“œκ°€ μƒνƒœλ³„λ‘œ κ΅¬λΆ„λ˜κΈ° λ•Œλ¬Έμ— μƒνƒœλ³„ λ™μž‘μ„ μˆ˜μ •ν•˜κΈ° 쉽닀.

λ”μš± λ³΅μž‘ν•œ 둜직이 μΆ”κ°€ λœλ‹€λ©΄ μƒνƒœ νŒ¨ν„΄μ€ 더 큰 빛을 λ³Ό 것이닀. 그리고 κΆκΈˆν•΄ ν•  수 있기 λ•Œλ¬Έμ— 같은 κΈ°λŠ₯을 ν•˜λŠ” enum μƒνƒœλ₯Ό κ΅¬ν˜„ν•΄ λ³΄μ•˜λ‹€.

Enum

public enum State {
    PERFECT("졜고 μž…λ‹ˆλ‹€."),
    HAPPY("행볡 ν•©λ‹ˆλ‹€"),
    SO_SO("κ·Έμ € κ·Έλž˜μš”."),
    BAD("λ³„λ‘œ μž…λ‹ˆλ‹€."),
    TERRIBLE("μ΅œμ•… μž…λ‹ˆλ‹€.");

    private String message;

    State(String message) {
        this.message = message;
    }

    public State winLottery() {
        return PERFECT;
    }

    // if (else if) 쑰건 λΆ„κΈ°λ‘œ μƒνƒœλ₯Ό μ²˜λ¦¬ν•œλ‹€.
    public State earnMoney() {
        if (this == TERRIBLE) {
            return BAD;
        }
        if (this == BAD) {
            return SO_SO;
        }
        if (this == SO_SO) {
            return HAPPY;
        }
        return PERFECT;
    }

    // μœ„μ™€ λ§ˆμ°¬κ°€μ§€λ‘œ switch 쑰건 λΆ„κΈ°λ‘œ μƒνƒœλ₯Ό μ²˜λ¦¬ν•œλ‹€.
    public State loseMoney() {
        switch (this) {
            case PERFECT:
                return HAPPY;
            case HAPPY:
                return SO_SO;
            case SO_SO:
                return BAD;
            default:
                return TERRIBLE;
        }
    }

    public State loseLottery() {
        return TERRIBLE;
    }

    public void printCurrentEmotion() {
        System.out.println(message);
    }
}

μœ„μ˜ μ˜ˆμ‹œμ²˜λŸΌ Sleep μ΄λΌλŠ” μƒνƒœλ₯Ό μΆ”κ°€ ν•œλ‹€λ©΄ enum 의 earnMoney() 와 loseMoney() λ₯Ό μˆ˜μ •ν•΄μ•Ό ν•œλ‹€.

SLEEP("μ‘Έλ¦½λ‹ˆλ‹€.");

 public State earnMoney() {
        if (this == TERRIBLE) {
            return BAD;
        }
        if (this == BAD) {
            return SO_SO;
        }
        if (this == SO_SO) {
            return HAPPY;
        }
        if (this == HAPPY) {
          	return PERFECT;
        }
        default:
            return SLEEP;
    }
}

public State loseMoney() {
        switch (this) {
            case PERFECT:
                return HAPPY;
            case HAPPY:
                return SO_SO;
            case SO_SO:
                return BAD;
            case BAD:
                return TERRIBLE;
            default:
                return SLEEP;
        }
}

enum ν•˜λ‚˜μ—μ„œ λͺ¨λ“  μƒνƒœλ₯Ό κ΄€λ¦¬ν•˜λŠ” 것은 μ’‹μ•„ 보일 수 μžˆλ‹€. ν•˜μ§€λ§Œ λ©”μ„œλ“œλ₯Ό μ‹€ν–‰ν•˜κΈ° μœ„ν•΄ 생긴 λ§Žμ€ λΆ„κΈ°λ₯Ό 보아라. μƒνƒœκ°€ κ³„μ†ν•΄μ„œ 생겨날 경우, κΈ°λŠ₯의 μˆ˜μ •μ΄ λ°œμƒν•˜λŠ” 경우, Enum 값을 if ν˜Ήμ€ switch 문으둜 νŒλ‹¨ν•˜λŠ” κ²½μš°μ—λŠ” OCP(κ°œλ°©νμ‡„μ›μΉ™)λ₯Ό μ€€μˆ˜ν•˜μ§€ λͺ»ν•œλ‹€. μƒνƒœκ°€ λ§Žμ•„μ§ˆμˆ˜λ‘ λ³΅μž‘ν•΄μ§€λŠ” 쑰건문이 μ—¬λŸ¬ μ½”λ“œμ—μ„œ μ€‘λ³΅ν•΄μ„œ μΆœν˜„ν•˜κ³  그만큼 μ½”λ“œ 변경을 μ–΄λ ΅κ²Œ λ§Œλ“ λ‹€.

μƒνƒœ νŒ¨ν„΄μ— λŒ€ν•΄ 이해가 λ°”λ‘œ λ˜μ§€λŠ” μ•Šμ„ 것이닀. ν”„λ‘œκ·Έλž¨μ„ ꡬ상할 λ•Œ μƒνƒœκ°€ ν•„μš”ν•œ κ³³μ—μ„œ μƒνƒœ νŒ¨ν„΄μ„ μ‚¬μš©ν•˜μ—¬ ν”„λ‘œκ·Έλž¨μ„ 섀계 해보닀 보면 μƒνƒœ νŒ¨ν„΄μ— λŒ€ν•œ 이해가 μžμ—°μŠ€λŸ½κ²Œ 될 것이닀. λ””μžμΈ νŒ¨ν„΄λΆ€ν„° ν•™μŠ΅ν•˜λŠ” λ°©μ‹λ³΄λ‹€λŠ” κ²½ν—˜μ„ ν† λŒ€λ‘œ κ΅¬ν˜„μ„ ν•΄λ³Έ ν›„ λ””μžμΈ νŒ¨ν„΄κ³Ό 비ꡐ해보며 ν•™μŠ΅ν•˜λŠ” 방식을 μΆ”μ²œν•œλ‹€.

μ°Έκ³