객체의 상태를 정의하는 데 사용되는 메소드를 정의하는 인터페이스
상태에 따른 동작을 정의하는 인터페이스
State에서 정의된 메소드를 구현하는 클래스
동전을 투입하면 티켓을 뽑을 수 있는 자판기
자판기의 상태:
1) 동전이 없는 상태
2) 동전이 투입 된 상태
public interface State {
void insertCoin();
void printTicket();
}
class CoinState implements State {
private final TicketMachine ticketMachine;
CoinState(TicketMachine ticketMachine) {
this.ticketMachine = ticketMachine;
}
@Override
public void insertCoin() {
System.out.println("이미 동전이 들어있습니다.");
}
@Override
public void printTicket() {
// 티켓을 출력하고, 동전을 동전 저장소에 추가한 다음, 동전이 없는 상태로 이동한다.
TicketPrinter.print();
CoinRepository.add(1);
ticketMachine.setState(ticketMachine.getNoCoinState());
}
}
class NoCoinState implements State {
TicketMachine ticketMachine;
NoCoinState(TicketMachine ticketMachine) {
this.ticketMachine = ticketMachine;
}
@Override
public void insertCoin() {
// 동전을 넣었다면 동전이 있는 상태로 이동한다.
ticketMachine.setState(ticketMachine.getCoinState());
}
@Override
public void printTicket() {
System.out.println("동전이 없습니다. 동전을 넣어주세요.");
}
}
public class TicketMachine {
final State noCoinState;
final State coinState;
private State currentState;
public TicketMachine() {
this.noCoinState = new NoCoinState(this);
this.coinState = new CoinState(this);
this.currentState = noCoinState;
}
public void insertCoin() {
currentState.insertCoin();
}
public void setState(State newState) {
this.currentState = newState;
}
public State getCoinState() {
return coinState;
}
public State getNoCoinState() {
return noCoinState;
}
}
한 번 인스턴스 생성 후, 상태를 바꾸는 경우가 빈번할 때 사용
한 번 인스턴스 생성 후에는 상태가 거의 바뀌지 않는 경우에 사용