ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Design Pattern] State Pattern
    Learn/Architecture 2022. 8. 29. 00:26

    # 개요

    • 객체가 내부적인 상태(state)에 따라 다르게 행동해야 할 때 사용하는 패턴
    • UML의 state machine diagram을 구현할 때 가장 적합한 패턴

    state에 따라 다르게 행동하도록 구현하는 가장 단순한 방법은 conditional statement를 쓰는 것이다. 

    public class GumballMachine {
        final static int SOLD_OUT = 0;
        final static int NO_QUARTER = 1;
        final static int HAS_QUARTER = 2;
        final static int SOLD = 3;
        int state = SOLD_OUT;
        int count = 0;
        
        public GumballMachine(int count) {
            this.count = count;
            if (count > 0) state = NO_QUARTER;
        }
        
        public void insertQuarter() {
            if (state == HAS_QUARTER) {
        ..
        }
        
        public void ejectQuarter() {
            if (state == HAS_QUARTER) {
        ..

    그러나 변경에 자유롭지 못하므로 좋은 방식이 아니다. 

     

    # State Pattern

    해결하기 위한 아이디어는,

    State Interface를 만들고 하위 클래스에서 action을 만들 수 있게 위임하는 것이다. 

     

    위 구조와 같이 Sold/SoldOut/NoQuarter/HasQuarter 각각의 상태에 따라 하위 클래스에서 구현한다. 

     

    예시로 아래의 insertQuater과 같이 state를 변화시키는 함수에서 set함수로 State를 바꿔준다. 

    public class NoQuarterState implements State {
        GumballMachine gumballMachine;
        public NoQuarterState(GumballMachine gumballMachine) {
            this.gumballMachine = gumballMachine;
        }
        
        public void insertQuarter() {
            System.out.println("You inserted a quarter");
            gumballMachine.setState(gumballMachine.getHasQuarterState());
        }
        ...
    }

    이와 같이 구성하면 OCP를 지킬 수 있다. 

     

    일반화해서 표현하면 다음과 같다. 

    State Pattern을 쓰면 State가 바뀔 때 마다 Behavior을 할 수 있다. 

     

    # State vs. Strategy

    • 클래스 다이어그램 상으로는 차이가 없다.
      • 어떤 문제를 해결하려 했는지(의도)가 다르다. 
    • State Pattern은 State에 dependency가 있는 behavior을 encapsulation하기 위해 사용
      • 안쓰면 conditional statement가 많이 생김
    • Strategy Pattern은 알고리즘을 encapsulation하기 위해 사용하고 상황에 따라 알고리즘이 바뀜
      • state pattern에 비해서는 바뀌는 빈도가 적음

    # Issue

    누가 state의 변경을 정의할 것인가?

    • 변경이 빈번하지 않고  단순할때는 Context Class를 만든다. 
    • 그렇지 않으면 ConcreteState 클래스에서 정의해주고 getter 함수를 제공한다. 

     

    Concrete object는 언제 만들 것인가?

    • 필요할때마다 만든다. 
    • 종류가 많지 않으면 처음에 만들어놔도 된다. 

    댓글

Designed by Tistory.