라떼군 이야기


12 / 13강

상태: 현재 단계에 맞는 동작 맡기기

문서가 초안일 때는 발행할 수 있지만 이미 발행됐다면 같은 요청을 거절해야 할 수 있습니다. 상태를 확인하는 조건문이 여러 메서드에 퍼지면 규칙을 빠뜨리기 쉽습니다. 상태 패턴은 현재 상태에 따라 달라지는 동작을 별도 객체로 나눕니다.

동작과 전이를 함께 봅니다

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로 바꾸면 어떤 문제가 생길까요?

해설 보기

실제로는 발행되지 않았는데 다음 요청은 이미 발행된 것으로 처리할 수 있습니다. 실제 작업의 성공과 상태 전이를 맞추어야 합니다. 외부 저장소나 동시 요청이 있다면 일관성을 보장하는 방식도 별도로 필요합니다.

제품 기획, 개발 파트너 찾으시나요? 개인, 팀, 기업 모두 환영. 문제 정의부터 출시까지 함께합니다.