๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Programming Language ๐Ÿ’ป/Java โ˜•

[Java] ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(OOP) - ์Šคํ…Œ์ดํŠธ ํŒจํ„ด(State Pattern)์ด๋ž€?

by lxvxxu 2025. 10. 18.

 

2025.10.18 - [๋ถ„๋ฅ˜ ์ „์ฒด๋ณด๊ธฐ] - [Java] ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(OOP) - 3. ๋””์ž์ธ ํŒจํ„ด์ด๋ž€?

 

[Java] ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(OOP) - 3. ๋””์ž์ธ ํŒจํ„ด์ด๋ž€?

3) ๋””์ž์ธ ํŒจํ„ด์ด๋ž€? ๐Ÿง ๋ฐ˜๋ณต๋˜๋Š” ์„ค๊ณ„ ๋ฌธ์ œ์— ๋Œ€ํ•œ ๊ฒ€์ฆ๋œ “์ด๋ฆ„ ์žˆ๋Š” ํ•ด๋ฒ•”์˜ ์นดํƒˆ๋กœ๊ทธ์žฅ์ : ๊ณตํ†ต ์–ดํœ˜ ์ œ๊ณต(์˜์‚ฌ์†Œํ†ต↑), ์žฌ์‚ฌ์šฉ์„ฑ↑, ์œ ์ง€๋ณด์ˆ˜์„ฑ↑์ฃผ์˜: “ํŒจํ„ด ์ ์šฉ์„ ์œ„ํ•ด ๋ฌธ์ œ๋ฅผ ์–ต์ง€๋กœ

lxvxxu.tistory.com


 


๐Ÿงฉ ๋””์ž์ธ ํŒจํ„ด  — ์Šคํ…Œ์ดํŠธ(State) ํŒจํ„ด

“๊ฐ์ฒด์˜ ๋‚ด๋ถ€ ์ƒํƒœ์— ๋”ฐ๋ผ ํ–‰๋™์„ ๋ฐ”๊พธ๋Š” ํŒจํ„ด”


๐ŸŽฏ ํ•™์Šต ๋ชฉํ‘œ

  • ์ƒํƒœ(State)์— ๋”ฐ๋ผ ๊ฐ์ฒด์˜ ๋™์ž‘์„ ๋‹ค๋ฅด๊ฒŒ ํ•˜๋Š” ๊ตฌ์กฐ๋ฅผ ์ดํ•ดํ•œ๋‹ค.
  • ์กฐ๊ฑด๋ฌธ(if/switch)์„ ์ œ๊ฑฐํ•˜๊ณ , ์ƒํƒœ ํด๋ž˜์Šค๋กœ ๋ถ„๋ฆฌํ•œ๋‹ค.

๐Ÿง  ์Šคํ…Œ์ดํŠธ ํŒจํ„ด์ด๋ž€?

Allow an object to alter its behavior when its internal state changes.
The object will appear to change its class.

โžก๏ธ ๊ฐ์ฒด์˜ ๋‚ด๋ถ€ ์ƒํƒœ๊ฐ€ ๋ฐ”๋€Œ๋ฉด ํ–‰๋™๋„ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋ฐ”๋€Œ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๊ฒŒ ๋งŒ๋“ ๋‹ค.


๐Ÿชซ ์˜ˆ์‹œ 1 — ํ˜•๊ด‘๋“ฑ ์ƒํƒœ ๊ด€๋ฆฌ

โš™๏ธ ๊ธฐ์กด ๋ฐฉ์‹

public class Light {
    private static final int ON = 0;
    private static final int OFF = 1;
    private static final int SLEEP = 2;
    private int state = OFF;

    public void on_button_pushed() {
        if (state == ON) { ... }
        else if (state == SLEEP) { ... }
        else { ... }
    }
}
 

โŒ ๋ฌธ์ œ์ 

  • ์ƒํƒœ๊ฐ€ ๋Š˜์–ด๋‚ ์ˆ˜๋ก if๋ฌธ์ด ๋ณต์žกํ•ด์ง
  • ์ƒํƒœ ์ถ”๊ฐ€ ์‹œ ๋ชจ๋“  ๋ฉ”์„œ๋“œ๋ฅผ ์ˆ˜์ •ํ•ด์•ผ ํ•จ

โœ… ํ•ด๊ฒฐ์ฑ… — ์ƒํƒœ ์บก์Аํ™”

interface LightState {
    void on_button_pushed(Light light);
    void off_button_pushed(Light light);
}

class ON implements LightState {
    public void on_button_pushed(Light light) { System.out.println("๋ฐ˜์‘ ์—†์Œ"); }
    public void off_button_pushed(Light light) {
        System.out.println("Light Off!");
        light.setState(new OFF());
    }
}

class OFF implements LightState {
    public void on_button_pushed(Light light) {
        System.out.println("Light On!");
        light.setState(new ON());
    }
    public void off_button_pushed(Light light) { System.out.println("๋ฐ˜์‘ ์—†์Œ"); }
}

class Light {
    private LightState state = new OFF();
    public void setState(LightState s) { state = s; }
    public void on_button_pushed() { state.on_button_pushed(this); }
    public void off_button_pushed() { state.off_button_pushed(this); }
}

โœ… ์ƒํƒœ ์ถ”๊ฐ€๊ฐ€ ์‰ฌ์›€
โœ… ์กฐ๊ฑด๋ฌธ ์ œ๊ฑฐ
โœ… ์ฝ”๋“œ ๊ฐ€๋…์„ฑ ํ–ฅ์ƒ


๐Ÿฌ ์˜ˆ์‹œ 2 — ๋ฝ‘๊ธฐ ๊ธฐ๊ณ„(Gumball Machine)

๋ฌธ์ œ ์ƒํ™ฉ

  • ๋™์ „ ํˆฌ์ž…, ์†์žก์ด ํšŒ์ „, ์•Œ๋งน์ด ๋ฐฐ์ถœ ๋“ฑ ์—ฌ๋Ÿฌ ์ƒํƒœ๊ฐ€ ์กด์žฌ
  • ๊ธฐ์กด ์ฝ”๋“œ์—์„œ๋Š” if (state == ...) ๋กœ ๋ชจ๋“  ์ƒํƒœ ์ œ์–ด

๐Ÿงฉ ์Šคํ…Œ์ดํŠธ ํŒจํ„ด ์ ์šฉ

  1. State ์ธํ„ฐํŽ˜์ด์Šค ์ •์˜
  2. ๊ฐ ์ƒํƒœ๋ฅผ ํด๋ž˜์Šค๋กœ ๊ตฌํ˜„ (NoQuarterState, HasQuarterState, SoldState, SoldOutState)
  3. GumballMachine ์€ ํ˜„์žฌ ์ƒํƒœ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐ
 
public class GumballMachine {
    State soldOutState, noQuarterState, hasQuarterState, soldState;
    State state;
    int count = 0;

    public GumballMachine(int count) {
        this.count = count;
        soldOutState = new SoldOutState(this);
        noQuarterState = new NoQuarterState(this);
        hasQuarterState = new HasQuarterState(this);
        soldState = new SoldState(this);
        state = (count > 0) ? noQuarterState : soldOutState;
    }

    public void insertQuarter() { state.insertQuarter(); }
    public void ejectQuarter() { state.ejectQuarter(); }
    public void turnCrank() { state.turnCrank(); state.dispense(); }
    void setState(State s) { this.state = s; }
}

๐Ÿ† ๊ฒฐ๊ณผ

  • ์ƒํƒœ๋ณ„ ๋™์ž‘์ด ๊ฐ ํด๋ž˜์Šค์— ๋ถ„๋ฆฌ๋˜์–ด ๊ด€๋ฆฌ ์šฉ์ด
  • ์ƒˆ๋กœ์šด ์ƒํƒœ(WinnerState) ์ถ”๊ฐ€๋„ ์ฝ”๋“œ ์ˆ˜์ • ๊ฑฐ์˜ ์—†์Œ

๐ŸŽ‰ ๋ณด๋„ˆ์Šค ๊ธฐ๋Šฅ — ๋‹น์ฒจ(Winner) ์ƒํƒœ ์ถ”๊ฐ€

public class WinnerState implements State {
    public void dispense() {
        System.out.println("์ถ•ํ•˜๋“œ๋ฆฝ๋‹ˆ๋‹ค! ์•Œ๋งน์ด 2๊ฐœ๋ฅผ ๋“œ๋ฆฝ๋‹ˆ๋‹ค!");
        // ... ๋‹น์ฒจ ์ฒ˜๋ฆฌ ๋กœ์ง
    }
}

โžก๏ธ ๊ธฐ์กด HasQuarterState์—์„œ ๋žœ๋ค ์กฐ๊ฑด ์ถ”๊ฐ€๋กœ ์—ฐ๊ฒฐ


๐Ÿ”š ์ •๋ฆฌ

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