상태 패턴(State Pattern)을 사용하면 객체의 내부 상태가 바뀜에 따라서 객체의 행동을 바꿀 수 있습니다. 마치 객체의 클래스가 바뀌는 것과 같은 결과를 얻을 수 있습니다.
public class GumballMachine {
State soldOutState;
State noQuarterState;
State hasQuarterState;
State soldState;
State winnerState;
State state;
int count = 0;
public GumballMachine(int numberGumballs) {
soldOutState = new SoldOutState(this);
noQuarterState = new NoQuarterState(this);
hasQuarterState = new HasQuarterState(this);
soldState = new SoldState(this);
winnerState = new WinnerState(this);
this.count = numberGumballs;
if (numberGumballs > 0) {
state = noQuarterState;
} else {
state = soldOutState;
}
}
public void insertQuarter() {
state.insertQuarter();
}
public void ejectQuarter() {
state.ejectQuarter();
}
public void turnCrank() {
state.turnCrank();
if (state == soldState || state == winnerState) {
state.dispense();
}
}
public void refill(int count) {
this.count += count;
state.refill();
}
void releaseBall() {
System.out.println("알맹이를 내보내고 있습니다.");
if (count > 0) {
count = count - 1;
}
}
}
public interface State {
void insertQuarter();
void ejectQuarter();
void turnCrank();
void dispense();
void refill();
}
// 각 State 구현체에서 다른 세부 로직 구현
public class HasQuarterState implements State {
Random randomWinner = new Random(System.currentTimeMillis());
GumballMachine gumballMachine;
public HasQuarterState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
}
@Override
public void insertQuarter() {
System.out.println("동전은 한 개만 넣어주세요.");
}
@Override
public void ejectQuarter() {
System.out.println("동전이 반환됩니다.");
this.gumballMachine.setState(gumballMachine.getNoQuarterState());
}
@Override
public void turnCrank() {
System.out.println("손잡이를 돌리셨습니다.");
int winner = randomWinner.nextInt(10);
if ((winner == 0) && (gumballMachine.getCount() > 1)) {
this.gumballMachine.setState(gumballMachine.getWinnerState());
} else {
this.gumballMachine.setState(gumballMachine.getSoldState());
}
}
@Override
public void dispense() {
System.out.println("알맹이를 내보낼 수 없습니다.");
}
@Override
public void refill() {
System.out.println("알맹이가 리필되었습니다.");
}
}
상태 패턴과 전략 패턴의 다이어그램은 똑같으나, 사용 용도가 다름. 상태 패턴과 전략 패턴 모두 Context 객체 내부의 구성 객체(상태 객체/전략 객체)에 일련의 행동이 캡슐화 되고, 상황에 따라 구성 객체를 선택해서 호출함.
상태 패턴에서는 Context 객체의 내부 상태에 따라 현재 상태를 나타내는 상태 객체가 바뀜, 클라이언트는 상태 객체를 몰라도 됨.
전략 패턴에서는 클라이언트가 Context 객체에게 어떤 전략 객체를 사용할 직접 지정함.
출처