개발공부/디자인패턴

[디자인 패턴] 상태 패턴 (State Pattern)

개발자 찐빵이 2023. 1. 31. 00:08
728x90

일을 하다가 State 어쩌고 하는 클래스가 있길래 봤는데 잘 이해가 안 갔다.
혹시나 디자인 패턴일까 찾아봤는데, 아니나 다를까
상태 패턴을 사용해서 설계한 방식이었다.

상태패턴이란?

상태 변경에 따라 객체의 행위가 달라져야 하는 상황에서
객체가 직접 상태를 체크하여 상태에 따른 행위를 호출하지 않고
상태를 객체화해서 상태가 필요한 행동할 수 있게 위임하는 디자인 패턴이다.

객체가 직접 상태를 체크해서 행위를 호출하면 뭐가 안 좋아?

코드로 보자.

class Document is
    field state: string
    // …
    method publish() is
        switch (state)
            "draft":
                state = "moderation"
                break
            "moderation":
                if (currentUser.role == "admin")
                    state = "published"
                break
            "published":
                // Do nothing.
                break
    // …

딱 봐도 복잡하다.
이런 조건문 기반의 상태머신은 상태가 많아질수록 더 복잡해지고, 유지보수가 어려워진다.

상태를 객체화시킨다?

상태 패턴은 가능한 모든 상태를 클래스로 만들고 상태별 행동을 클래스로 추출할 것을 제안하고 있다.
즉, 특정 행위(함수)가 호출되면, 해당 함수를 오버라이딩한 함수들 중에 현재 상태에 맞는 함수를 찾아서 호출한다.

상태패턴의 구조

상태 패턴은 Context, State, ConcreteStates, Client로 나눌 수 있다.

Context

State Interface를 통해 상태 객체와 통신하는 객체.
새로운 상태 객체를 전달하기 위해 Setter를 노출한다.
ConcreateStates 객체 중 하나에 대한 참조를 저장하고, 모든 상태별 작업을 ConcreteStates에 위임한다.

State

상태별 메서드들이 선언된 인터페이스.
이 메서드들은 모든 ConcreteStates 객체에서 유효해야 한다. (모두 오버라이드 되어야 함.)

ConcreteStates

각 상태별 메서들에 대한 자체적인 행위를 구현한 객체.
코드 중복을 피하기 위해 캡슐화, 추상 클래스 등을 제공할 수 있다.
Context를 참조하고 상태 변경을 할 수 있다.

특징

Context와 ConcreteStates는 모두 Context의 다음 상태를 설정할 수 있다.
또는 Context에 연결된 상태 객체를 교체해서 상태를 변경할 수 있다.

참고

상태 패턴

반응형