상태: 현재 단계에 맞는 동작 맡기기
문서가 초안일 때는 발행할 수 있지만 이미 발행됐다면 같은 요청을 거절해야 할 수 있습니다. 상태를 확인하는 조건문이 여러 메서드에 퍼지면 규칙을 빠뜨리기 쉽습니다. 상태 패턴은 현재 상태에 따라 달라지는 동작을 별도 객체로 나눕니다.
동작과 전이를 함께 봅니다
class Draft:
def publish(self, document):
document.state = Published()
return "published"
class Published:
def publish(self, document):
return "already published"
class Document:
def __init__(self):
self.state = Draft()
def publish(self):
return self.state.publish(self)
document = Document()
print(document.publish())
print(document.publish())
출력은 published, already published입니다. 처음 publish는 Draft에 전달되고, Draft가 작업을 처리한 뒤 Published로 상태를 바꿉니다. 다음 호출은 Published의 규칙을 따릅니다.
상태 객체를 만든 뒤에도 어떤 전이가 가능한지 표나 그림으로 정리하는 것이 좋습니다. 예제는 초안 → 발행만 허용합니다. 발행 취소가 필요하다면 누가 어떤 조건에서 초안으로 되돌릴 수 있는지 추가로 설계해야 합니다.
전략과 모양은 비슷해도 목적이 다릅니다
전략은 교체 가능한 계산 방법에 초점을 둡니다. 상태는 대상의 현재 단계와 그 단계에서 허용되는 동작에 초점을 둡니다. 두 상태뿐이고 조건도 짧다면 enum과 조건문이 더 읽기 쉬울 수 있습니다. 상태별 규칙이 커질 때 분리의 효과를 비교하세요.
확인 문제
발행에 실패했는데도 먼저 Published로 바꾸면 어떤 문제가 생길까요?
해설 보기
실제로는 발행되지 않았는데 다음 요청은 이미 발행된 것으로 처리할 수 있습니다. 실제 작업의 성공과 상태 전이를 맞추어야 합니다. 외부 저장소나 동시 요청이 있다면 일관성을 보장하는 방식도 별도로 필요합니다.