State Pattern (스테이트 패턴)
State Pattern
정의
Object의 내부 상태가 바뀜에 따라서 object의 행동을 바꿀 수 있다.
마치 object의 class가 바뀌는 것과 같은 결과를 얻을 수 있다.
State pattern은 state를 class로 표현한다.
그 이유는, class의 교체를 통해서 state의 변화를 나타낼 수 있고, 새로운 state를 추가해야 할 때, 편리하기 때문이다.
적용 영역
1. Object의 행위가 object의 state에 의존하고 그 object의 행위가 실행 시점에서 object의 state에 따라 변화해야 할 경우
2. Operation이 크고, object의 state에 따라 다수의 조건문을 포함하는 경우
State vs Strategy (pattern)
State pattern을 사용할 때는 state object의 행동이 캡슐화 된다.
State에 따라 context object에서 여러 state object 중 한 object에게 모든 행동을 위임한다.
해당 object의 내부 state에 따라 현재 state를 나타내는 object가 바뀌고,
그 결과 context object의 행동도 바뀐다. Client는 state object에 대해서 몰라도 된다.
하지만, strategy pattern은 client에서 context object한테 어떤 object를 사용할지 정한다.
Strategy pattern은 주로 실행시에 전략 object를 변경할 수 있는 유연성을 제공하기 위한 용도로 쓰이며, 가장 적합한 전략 object를 선택해서 사용한다.
즉, strategy pattern은 외부에서 상황에 맞게 변화를 줄 수 있고, state pattern은 자신이 직접 상태변화에 관여한다는 것이다
구성요소
1. State를 나타내는 state
2. state간의 전의를 표현하는 action
3. state 전이에 나타나는 onEntry, onExit 함수
소스코드
Action(enum)
public enum Action {
EAT, DIGEST, GOTOBED;
}
State(enum)
public enum State {
HUNGRY{
public State act(Action action){
switch (action){
case EAT: return FULL;
default: return null;
}
}
},
FULL{
public State act(Action action){
switch (action){
case EAT: return ANGRY;
case DIGEST: return HUNGRY;
case GOTOBED: return SLEEPING;
default: return null;
}
}
},
ANGRY{
public State act(Action action){
switch (action){
case DIGEST: return FULL;
default: return null;
}
}
},
SLEEPING{
public void onEntry(){
System.out.println("go bed");
}
public State act(Action action){
return null;
}
};
abstract State act(Action action);
public static State getInitState(){
return HUNGRY;
}
public static boolean isFinalState(State state){
return state==SLEEPING;
}
public void onEntry(){}
public void onExit(){}
}
StateContext(class)
public class StateContext {
private State currentState;
public StateContext(){
currentState = State.getInitState();
}
public void processEvent(Action action){
State next= currentState.act(action);
if(next != null){
currentState.onExit();
System.out.println(action +"에 의해 State가 " +
currentState+"에서 "+next+"로 바뀜");
currentState=next;
currentState.onEntry();
if(State.isFinalState(currentState)){
System.out.println("i'm final State");
}
}else{
System.out.println(action+"은 state가 " +currentState
+"에서는 의미 없는 짓");
}
}
}
Main
public class Main {
public static void main(String[] args){
StateContext context = new StateContext();
context.processEvent(Action.EAT);
context.processEvent(Action.EAT);
context.processEvent(Action.GOTOBED);
context.processEvent(Action.DIGEST);
context.processEvent(Action.EAT);
context.processEvent(Action.GOTOBED);
context.processEvent(Action.DIGEST);
context.processEvent(Action.GOTOBED);
}
}
결과
UML
'SW > DesignPattern' 카테고리의 다른 글
Compound Pattern (컴파운드 패턴) (0) | 2017.09.19 |
---|---|
Proxy Pattern (프록시 패턴) (0) | 2017.09.18 |
Composite Pattern (컴포지트 패턴) (0) | 2017.09.15 |
Iterator Pattern (반복자 패턴) (0) | 2017.09.14 |
Template Method Pattern (템플릿메소드패턴) (0) | 2017.09.11 |