State Pattern

윤세영·2023년 7월 6일
0

DesignPattern

목록 보기
3/15

정의

  • Object의 내부 상태가 바뀜에 따라서 object의 행동을 바꿀 수 있다.
  • 마치 object의 class가 바뀌는 것과 같은 결과를 얻을 수 있다.
  • State pattern은 state를 class로 표현한다.
    그 이유는, class의 교체를 통해서 state의 변화를 나타낼 수 있고, 새로운 state를 추가해야 할 때, 편리하기 때문이다.

적용 영역

  • Object의 행위가 object의 state에 의존하고 그 object의 행위가 실행 시점에서 object의 state에 따라 변화해야 할 경우
  • 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은 자신이 직접 상태변화에 관여한다는 것이다

구성요소

  • State를 나타내는 state
  • state간의 전의를 표현하는 action
  • 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

profile
Frontend

0개의 댓글

관련 채용 정보