A A
[Design Pattern] State Pattern - μƒνƒœ νŒ¨ν„΄

State Pattern

μƒνƒœ νŒ¨ν„΄(State Pattern)은 객체가 λ‚΄λΆ€ μƒνƒœμ— 따라 행동을 λ‹€λ₯΄κ²Œ ν•  수 있게 ν•΄μ£ΌλŠ” λ””μžμΈ νŒ¨ν„΄μž…λ‹ˆλ‹€.
  • κ°μ²΄λŠ” μƒνƒœλ₯Ό λ³€κ²½ν•¨μœΌλ‘œμ¨ 행동이 λ°”λ€λ‹ˆλ‹€.
  • μƒνƒœ νŒ¨ν„΄μ„ μ‚¬μš©ν•˜λ©΄ 쑰건문을 많이 μ‚¬μš©ν•˜λŠ” μ½”λ“œλ₯Ό κ°„κ²°ν•˜κ³  ν™•μž₯ κ°€λŠ₯ν•˜κ²Œ λ§Œλ“€ 수 μžˆμŠ΅λ‹ˆλ‹€.
  • StateλŠ” μƒνƒœ = μ‚¬λ¬Όμ˜ λͺ¨μ–‘μ΄λ‚˜ ν˜•νŽΈμ„ μ˜λ―Έν•©λ‹ˆλ‹€.
  • λ˜ν•œ μƒνƒœλ₯Ό 클래슀둜 ν‘œν˜„ν•˜λ©΄ 클래슀λ₯Ό κ΅μ²΄ν•΄μ„œ 'μƒνƒœμ˜ λ³€ν™”'λ₯Ό ν‘œν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • Strategy Patternκ³Ό 쑰금 μœ μ‚¬ν•©λ‹ˆλ‹€.

 

 

μš°λ¦¬κ°€ λ§Œλ“€κ³ μž ν•˜λŠ” Object에 μƒνƒœκ°€ μžˆλ‹€λ©΄ μ‚¬μš©ν•  수 μžˆλŠ” Pattern μž…λ‹ˆλ‹€.

 

  • μƒνƒœλ₯Ό κ°€μ§€λŠ” κ°€μž₯ λŒ€ν‘œμ μΈ μ˜ˆκ°€ μ‹ ν˜Έλ“± μž…λ‹ˆλ‹€.
  • 녹색, 빨강색 쀑 ν•˜λ‚˜μ˜ μƒνƒœλ§Œ κ°€μ§€λŠ” 기계이며, κ³„μ†ν•΄μ„œ μƒνƒœκ°€ λ³€ν™”λ©λ‹ˆλ‹€.

State Pattern을 μ‚¬μš©ν•˜μ§€ μ•Šμ€ μ½”λ“œ

class TrafficLight:
    def __init__(self):
        self.state = 'green'

    def setState(self, state: str):
        self.state = state

    def speak(self):
        if self.state == 'green':
            print('green light')
        elif self.state == 'red':
            print('red light')

    def wait(self):
        print('wait.. the light changed')
        if self.state == 'green':
            self.state = 'red'
        elif self.state == 'red':
            self.state = 'green'

 

  • __init__
    • κΈ°λ³Έ stateλŠ” 'green'으둜 μ„€μ •ν•©λ‹ˆλ‹€.
  • setState
    • ν˜„μž¬ stateλ₯Ό μ„€μ •ν•  수 μžˆλŠ” ν•¨μˆ˜μž…λ‹ˆλ‹€.
  • speak
    • ν˜„μž¬ state에 따라 'green light' λ˜λŠ” 'red light'λ₯Ό 좜λ ₯ν•©λ‹ˆλ‹€.
  • wait
    • 호좜 μ‹œ stateκ°€ λ³€κ²½λ˜λ©°, 'wait.. the light changed'λ₯Ό 좜λ ₯ν•©λ‹ˆλ‹€.

 

# 예제 μ‚¬μš©
t_light = TrafficLight()
t_light.speak()   # 좜λ ₯: green light
t_light.wait()    # 좜λ ₯: wait.. the light changed
t_light.speak()   # 좜λ ₯: red light

 

  • TrafficLight 객체인 t_light 을 μƒμ„±ν•©λ‹ˆλ‹€.
  • speak() 호좜 μ‹œ ν˜„μž¬ stateλŠ” greenμ΄λ―€λ‘œ 'green light' κ°€ 좜λ ₯λ©λ‹ˆλ‹€.
  • wait() 호좜 μ‹œ stateκ°€ red둜 λ³€κ²½λ˜λ©° 'wait.. the light changed' κ°€ 좜λ ₯λ©λ‹ˆλ‹€.
  • speak() 호좜 μ‹œ stateλŠ” redμ΄λ―€λ‘œ 'red light' κ°€ 좜λ ₯λ©λ‹ˆλ‹€.

 

ν•˜μ§€λ§Œ, Stateκ°€ λ§Žμ•„μ§„λ‹€λ©΄ ν˜„μž¬ μ½”λ“œ κ΅¬μ‘°λ‘œλŠ” λ³΅μž‘μ„±μ„ λŒ€μ‘ν•˜κΈ°κ°€ μ–΄λ ΅μŠ΅λ‹ˆλ‹€.

μ΄λ•Œ State Pattern을 μ΄μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

State Pattern 클래슀 ꡬ쑰

 


TrafficLight Class

class TrafficLight:
    def __init__(self):
        self.state = GreenLight()

    def setState(self, state):
        self.state = state

    def speak(self):
        self.state.status()

    def wait(self):
        self.state.changeLight(self)

 

 

TrafficLight 클래슀

    • κΈ°λ³Έ μƒνƒœλ‘œ GreenLight 객체λ₯Ό κ°€μ§‘λ‹ˆλ‹€.
    • setState λ©”μ„œλ“œλ₯Ό 톡해 μƒνƒœλ₯Ό λ³€κ²½ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
    • speak λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λ©΄ ν˜„μž¬ μƒνƒœ 객체의 status λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜μ—¬ μƒνƒœλ₯Ό 좜λ ₯ν•©λ‹ˆλ‹€.
    • wait λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λ©΄ ν˜„μž¬ μƒνƒœ 객체의 changeLight λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜μ—¬ μƒνƒœλ₯Ό λ³€κ²½ν•©λ‹ˆλ‹€.

 

State 클래슀 및 ꡬ체적인 μƒνƒœ 클래슀

class State:
    def status(self):
        pass

    def changeLight(self, traffic_light: TrafficLight):
        pass

class GreenLight(State):
    def status(self):
        print('green light')

    def changeLight(self, traffic_light: TrafficLight):
        print('wait.. the light changed')
        traffic_light.setState(RedLight())

class RedLight(State):
    def status(self):
        print('red light')

    def changeLight(self, traffic_light: TrafficLight):
        print('wait.. the light changed')
        traffic_light.setState(GreenLight())

 

 

 

  • State 클래슀
    • μƒνƒœ 객체듀이 μƒμ†λ°›λŠ” 좔상 ν΄λž˜μŠ€μž…λ‹ˆλ‹€.
    • status λ©”μ„œλ“œλŠ” ν˜„μž¬ μƒνƒœλ₯Ό 좜λ ₯ν•©λ‹ˆλ‹€.
    • changeLight λ©”μ„œλ“œλŠ” μƒνƒœλ₯Ό λ³€κ²½ν•©λ‹ˆλ‹€.
  • GreenLight 클래슀
    • State 클래슀λ₯Ό 상속받아 κ΅¬ν˜„λœ ν΄λž˜μŠ€μž…λ‹ˆλ‹€.
    • status λ©”μ„œλ“œλŠ” "green light"λ₯Ό 좜λ ₯ν•©λ‹ˆλ‹€.
    • changeLight λ©”μ„œλ“œλŠ” TrafficLight 객체의 μƒνƒœλ₯Ό RedLight둜 λ³€κ²½ν•©λ‹ˆλ‹€.
  • RedLight 클래슀
    • State 클래슀λ₯Ό 상속받아 κ΅¬ν˜„λœ ν΄λž˜μŠ€μž…λ‹ˆλ‹€.
    • status λ©”μ„œλ“œλŠ” "red light"λ₯Ό 좜λ ₯ν•©λ‹ˆλ‹€.
    • changeLight λ©”μ„œλ“œλŠ” TrafficLight 객체의 μƒνƒœλ₯Ό GreenLight둜 λ³€κ²½ν•©λ‹ˆλ‹€.

 

t_light = TrafficLight()
t_light.speak()   # 좜λ ₯: green light
t_light.wait()    # 좜λ ₯: wait.. the light changed
t_light.speak()   # 좜λ ₯: red light
  • λ™μž‘ μ˜ˆμ‹œ
    • t_light 객체λ₯Ό μƒμ„±ν•˜κ³  speak λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λ©΄ ν˜„μž¬ μƒνƒœμΈ "green light"κ°€ 좜λ ₯λ©λ‹ˆλ‹€.
    • wait λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λ©΄ μƒνƒœκ°€ RedLight둜 λ³€κ²½λ˜κ³  "wait.. the light changed"κ°€ 좜λ ₯λ©λ‹ˆλ‹€.
    • λ‹€μ‹œ speak λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λ©΄ ν˜„μž¬ μƒνƒœμΈ "red light"κ°€ 좜λ ₯λ©λ‹ˆλ‹€.

κ°œλ… ν™•μž₯

Divide and Conquer

  • 주어진 문제λ₯Ό μž‘μ€ λ¬Έμ œλ“€λ‘œ λ‚˜λˆ„μ–΄μ•Ό ν•©λ‹ˆλ‹€.
  • 각각의 ꡬ체적인 μƒνƒœλ₯Ό 각각의 클래슀둜 ν‘œν˜„ν•΄μ„œ 문제λ₯Ό λΆ„ν• ν•œ κ²ƒμž…λ‹ˆλ‹€.
  • State νŒ¨ν„΄μ„ μ‚¬μš©ν•˜μ§€ μ•ŠμœΌλ©΄ μƒνƒœκ°€ 많으면 λ§Žμ„μˆ˜λ‘ 쑰건 뢄기도 μ¦κ°€ν•©λ‹ˆλ‹€.
  • λΉ„μŠ·ν•œ 쑰건뢄기λ₯Ό 사건이 λ°œμƒν•  λ•Œλ§ˆλ‹€ ν˜ΈμΆœλ˜λŠ” λ©”μ†Œλ“œμ— μ „λΆ€ κΈ°μˆ ν•΄ μ£Όμ–΄μ•Ό ν•©λ‹ˆλ‹€.
  • State νŒ¨ν„΄μ€ μ‹œμŠ€ν…œμ˜ μƒνƒœλ₯Ό 클래슀둜 ν‘œν˜„ν•΄μ„œ λ³΅μž‘ν•œ ν”„λ‘œκ·Έλž¨μ„ λΆ„ν• ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

 

State의 μ „ν™˜μ€ λˆ„κ°€ 관리해야 ν•˜λŠ”κ°€?

  • μƒνƒœλ₯Ό 클래슀둜 ν‘œν˜„ν•΄μ„œ ConcreteState 역할에 λΆ„λ‹΄ν•˜λŠ” 것은 쒋은 λ°©λ²•μž…λ‹ˆλ‹€.
  • κ·ΈλŸ¬λ‚˜ State νŒ¨ν„΄μ„ μ‚¬μš©ν•  경우 μƒνƒœ μ „ν™˜μ€ λˆ„κ°€ 관리해야 ν•˜λŠ”μ§€ 생각해 봐야 ν•©λ‹ˆλ‹€.
  • Context μ—­ν• μ˜ Traffic Lightκ°€ μƒνƒœ μ „ν™˜μ„ μ‹€μ œλ‘œ μˆ˜ν–‰ν•˜λ„λ‘ setStateλ₯Ό κ΅¬ν˜„ν•˜μ˜€μŠ΅λ‹ˆλ‹€.
  • κ·ΈλŸ¬λ‚˜ setStateλ₯Ό μ‹€μ œλ‘œ ν˜ΈμΆœν•˜λŠ” 것은 ConcreteState μ—­ν• μ˜ GreenLight λ˜λŠ” RedLight ν΄λž˜μŠ€μž…λ‹ˆλ‹€.
  • 즉, μƒνƒœ μ „ν™˜μ„ μƒνƒœμ— μ˜μ‘΄ν•œ λ™μž‘μœΌλ‘œ κ°„μ£Όλ˜κ³  μžˆλŠ”λ°, 이것은 μž₯단점이 μžˆμŠ΅λ‹ˆλ‹€.
    • μž₯점: λ‹€λ₯Έ μƒνƒœλ‘œ μ „ν™˜ν•˜λŠ” 것에 λŒ€ν•œ 정보가 ν•˜λ‚˜μ˜ 클래슀 내에 μ •λ¦¬λ˜μ–΄ 있고, κ°€λ Ή GreenLight ν΄λž˜μŠ€κ°€ μ–΄λ–€ μƒνƒœλ‘œ μ „ν™˜ν•˜λŠ”μ§€λŠ” GreenLight 클래슀 μ½”λ“œλ§Œ 읽으면 λ©λ‹ˆλ‹€.
    • 단점: ν•˜λ‚˜μ˜ ConcreteState 역할이 λ‹€λ₯Έ ConcreteState 역할을 μ„œλ‘œ μ•Œμ•„μ•Ό ν•œλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. 이것은 λ§Œμ•½ ν•˜λ‚˜λ₯Ό μ‚­μ œν•˜κ³  μ‹ΆμœΌλ©΄ 의쑴된 또 λ‹€λ₯Έ 것도 μˆ˜μ •ν•΄μ•Ό ν•œλ‹€λŠ” 것을 μ˜λ―Έν•©λ‹ˆλ‹€.
  • μƒνƒœ μ „ν™˜μ„ ConcreteStateμ—κ²Œ 맑기면 클래슀 μ‚¬μ΄μ˜ μ˜μ‘΄κ΄€κ³„κ°€ κΉŠμ–΄μ§‘λ‹ˆλ‹€.

 

Context μ—­ν• μ—κ²Œ μƒνƒœ μ „ν™˜μ˜ 업무λ₯Ό 맑기면 λ˜μ§€ μ•ŠλŠ”κ°€?

  • κ·Έλ ‡κ²Œ 되면 각각의 ConcreteState μ—­ν• μ˜ 독립성이 λ†’μ•„μ§€λŠ” 것은 μ’‹μŠ΅λ‹ˆλ‹€.
  • κ·ΈλŸ¬λ‚˜ μ΄λ²ˆμ—λŠ” Context 역할이 λͺ¨λ“  ConcreteState 역할을 μ•Œμ•„μ•Ό ν•˜λŠ” λ¬Έμ œκ°€ λ°œμƒν•©λ‹ˆλ‹€.