위의 예제는 현재 상태에 따라서 수행하는 동작이 달라지는 Gumball Machine을 구현한 것입니다.
각 메소드는 아래와 같이 현재 상태에 따라서 수행하는 동작이 달라지게 됩니다.
GumballMachine.java
public void insertQuarter() {
switch (state) {
case SOLD_OUT:
System.out.println("SOLD OUT");
break;
case NO_QUARTER:
state = HAS_QUARTER;
System.out.println("Inserted quarter");
break;
case HAS_QUARTER:
System.out.println("Please insert only one quarter");
break;
case SOLD:
System.out.println("Please wait for a second. The gumball is going out");
break;
}
}
스테이트 패턴을 적용하면 아래와 같이 적용할 수 있습니다.
GumballMachine.java
public class GumballMachine {
State soldOutState;
State noQuarterState;
State hasQuarterState;
State soldState;
State winnerState;
// 현재 state
State state = soldOutState;
int count;
...
public void insertQuarter() {
state.insertQuarter();
}
...
}
NoQuaterState.java
@Override
public void insertQuarter() {
System.out.println("Inserted quarter");
machine.setState(machine.getHasQuarterState());
}
위의 코드처럼 기존에는 if 문으로 모든 상태에 대해 각 행동을 정해줘야했지만, 이제 State
클래스에서 각 상태에 맞게 동작을 수행하고 상태를 변경해줍니다.
구현을 구조적으로 바꾸면서 크게 아래 다섯 가지 이점을 얻을 수 있었습니다.
GumballMachine
자체는 새로운 상태 클래스를 추가하는 확장에 대해서 열려있도록 고쳤습니다. (OCP)스테이트 패턴(State Pattern)을 이용하면 객체의 내부 상태가 바뀜에 따라서 객체의 행동을 바꿀 수 있습니다. 마치 객체의 클래스가 바뀌는 것과 같은 결과를 얻을 수 있습니다.