상태 패턴
Coddy Python 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 64개 중 53번째.
State Pattern을 사용하면 객체는 내부 상태가 변경될 때 동작을 변경할 수 있습니다. 객체는 현재 상태에 따라 클래스가 변경되는 것처럼 보입니다.
신호등을 위한 간단한 상태 클래스는 다음과 같습니다:
class RedState:
def next_state(self, light):
print("Red -> Green")
light.state = GreenState()
def current_color(self):
return "Red"
class GreenState:
def next_state(self, light):
print("Green -> Yellow")
light.state = YellowState()
def current_color(self):
return "Green"
class YellowState:
def next_state(self, light):
print("Yellow -> Red")
light.state = RedState()
def current_color(self):
return "Yellow"각 상태는 다음 상태로 전환할 때 발생하는 동작을 정의합니다.
현재 상태를 보유하는 컨텍스트 클래스를 만드세요:
class TrafficLight:
def __init__(self):
self.state = RedState() # 빨간색으로 시작
def change(self):
self.state.next_state(self)
def get_color(self):
return self.state.current_color()신호등은 현재 상태 객체에 동작을 위임합니다.
신호등을 사용하세요:
light = TrafficLight()
print(f"Current: {light.get_color()}")
light.change() # 빨간색 -> 초록색
print(f"Current: {light.get_color()}")
light.change() # 초록색 -> 노란색
print(f"Current: {light.get_color()}")
light.change() # 노란색 -> 빨간색
print(f"Current: {light.get_color()}")간단한 플레이어로 또 다른 예제를 만들어 보세요:
class PlayingState:
def play(self, player):
print("Already playing")
def stop(self, player):
print("Stopping music")
player.state = StoppedState()
class StoppedState:
def play(self, player):
print("Starting music")
player.state = PlayingState()
def stop(self, player):
print("Already stopped")
class MusicPlayer:
def __init__(self):
self.state = StoppedState()
def play(self):
self.state.play(self)
def stop(self):
self.state.stop(self)
player = MusicPlayer()
player.play() # 음악 시작
player.play() # 이미 재생 중
player.stop() # 음악 중지
player.stop() # 이미 중지됨출력:
Current: Red
Red -> Green
Current: Green
Green -> Yellow
Current: Yellow
Yellow -> Red
Current: Red
Starting music
Already playing
Stopping music
Already stopped핵심 요점: 상태 패턴은 상태별 동작을 별도의 클래스에 캡슐화하고 컨텍스트 객체가 현재 상태에 위임하도록 합니다. 상태가 변경되면 동작도 자동으로 변경됩니다. 이를 통해 복잡한 if/else 문을 없애고 새로운 상태를 더 쉽게 추가할 수 있습니다.
챌린지
쉬움버튼 하나가 있는 램프에 대한 State 패턴을 state.py에 구현하세요. 버튼을 누를 때마다 램프는 세 가지 상태를 순환합니다: 꺼짐, 약한 밝기, 강한 밝기, 그리고 다시 꺼짐으로 돌아갑니다. 문자열에 대한 if 체인을 사용하는 대신, 각 상태는 버튼을 눌렀을 때 어떤 일이 일어나는지 알고 있는 고유한 객체입니다.
LampState는press(lamp)와describe()를 포함하는 기본 클래스입니다.OffState,LowState,HighState는 이를 구현합니다.press는 다음 상태를 인수로 하여lamp.set_state(...)를 호출하고(꺼짐에서 약한 밝기, 약한 밝기에서 강한 밝기, 강한 밝기에서 꺼짐),describe는Lamp is off,Lamp is on low또는Lamp is on high를 반환합니다.Lamp는 컨텍스트입니다.OffState에서 시작하고,set_state는 상태 객체를 교체하며,press_button은 현재 상태에 처리를 위임하고,status는 현재 설명을 반환합니다.
driver.py는 잠겨 있습니다. 이 파일은 버튼을 누르고 상태를 출력합니다. Lamp는 현재 어떤 상태인지 전혀 확인하지 않으며, 상태 객체가 이를 결정한다는 점에 주목하세요.
직접 해보기
from state import Lamp
# 테스트 케이스 핸들러 (변경하지 마세요)
test_case = input()
lamp = Lamp()
if test_case == "initial_test":
print(lamp.status())
elif test_case == "one_press_test":
lamp.press_button()
print(lamp.status())
elif test_case == "cycle_test":
for _ in range(4):
print(lamp.status())
lamp.press_button()
elif test_case == "many_presses_test":
for _ in range(7):
lamp.press_button()
print(lamp.status())
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 Python 컴파일러