디자인 패턴 - 스테이트 패턴(State pattern)

정의 : 객체의 내부 상태가 바뀜에 따라서 객체의 행동을 바꿀 수 있다. 마치 객체의 클래스가 바뀌는 것과 같은 결과를 얻을 수 있다.

 스테이트 객체로 일련의 행동을 캡슐화하고 이를 컨텍스트 객체에서 상태에 따라 갈아낀다. 그러면 컨텍스트 객체는 자신의 상태에 따라 스테이트 객체의 행동을 하게 된다.
 상태를 기반으로 하는 행동을 캡슐화하고, 행동을 현재 상태한테 위임한다.
상태 전환은 스테이트 클래스에서 제어할 수도 있고, 컨텍스트 클래스에서 제어할 수도 있다.


 스트래티지 패턴과 같은 방식으로 행동을 상속해서 사용한다.
스테이트 패턴은 상황에 따라 컨텍스트(Context) 객체에서 여러 스테이트 객체 중 하나가 내부 상태를 나타내고, 이 스테이트 객체에 따라 컨텍스트 객체의 행동도 자연스럽게 바뀐다. 클라이언트는 상태 객체에 대해 몰라도 상관 없다.

 이 점에서 스트래티지 패턴과의 차이가 있다. 스트래티지 패턴을 사용할 때에는 클라이언트에서 컨텍스트 객체에게 어떤 전략(Stratege) 객체를 사용할지를 지정해준다.

일반적으로 스트래티지 패턴은 서브클래스를 만드는 대신 행동을 상속하여 유연성을 극대화시키기 위해 쓰인다. 스트래티지 패턴을 사용하면 구성을 통해 행동을 정의하는 객체를 유연하게 바꿀 수 있다. 바꿔 쓸 수 있는 행동을 캡슐화한 다음, 실제 행동은 다른 객체에 위임한다.

스테이트 패턴은 상태 객체를 바꾸는 것만으로 컨텍스트 객체의 행동을 바꿀 수 있다.

애니메이션 상태 제어, 유닛의 상태변경(공격<->대기<->이동 등) 등에 쓰일 수 있다.
유한 상태 기계(FSM)을 구현하는 좋은 방법이다.


예시:

State { Handle() }
IdleState : State { Handle(){ IdleAnimation.Play }
MoveState : State { Handle() { MoveAnimation.Play }
Context { Handle(){ currentState.Handle(); }

Client.Context.SetState(MoveState) } // Additional behavior can be executed when state changed.
//State changed. Thus context behavior changed.
Client.Context.Handle(); // Context executes the behavior according to current state

댓글

이 블로그의 인기 게시물

디자인 패턴 - 더티 플래그(Dirty flag)

디자인 패턴 - 서비스 중개자 패턴(Service locator pattern)

인공지능 - 유한 상태 기계(Finite state machine)