08. State Pattern

Jimin Lim·2021년 11월 17일
0

Design Pattern

목록 보기
9/12
post-thumbnail

객체의 내부 상태가 바뀔 때 객체의 동작을 변경할 수 있도록 한다.
객체는 자신의 클래스를 바꾸는 것처럼 보인다.

  • State: 시점에 따라 특정 상태에 있어야 한다.
  • Transition: 외부 입력에 따라 가능한 상태로 전환한다.

Problem

상태가 여러 개 일때, if문으로 상태를 통제한다. if문으로 통제하게 된다면 하나를 수정한다면 수정할 부분이 많아진다.

*상태
게임 캐릭터: 걷는 상태, 뛰는 상태, 멈춘 상태
가전 제품: on, off, sleep...

Solution

  • 모든 상태에 대해 상태 클래스를 구현하도록 한다.

예시 - 뽑기 기계

뽑기 기계 상태 정의

  • 매진, 동전 없음, 동전 있음, 판매

뽑기 행동 모음

  • 동전 투입, 손잡이 돌림, 알맹이 내보냄, 동전 반환
public interface State {
    public void insertQuarter(); // 동전 투입
    public void turnCrank(); //손잡이 돌림
    public void dispense(); //알맹이 내보냄
    public void ejectQuarter(); //동전 반환
}

각 상태에서 행동이 실행된다면 진행할 코드 작성

//동전을 가지고 있는 상태
public class HasQuarterState implements State{
    GumballMachine gumballMachine;

    public HasQuarterState(GumballMachine gumballMachine) {
        this.gumballMachine = gumballMachine;
    }

    @Override
    public void insertQuarter() {
        System.out.println("동전은 하나만 넣어주세요");
    }

    @Override
    public void turnCrank() { //판매 상태로 전환
        System.out.println("손잡이를 돌리셨습니다.");
        gumballMachine.setState(gumballMachine.getSoldState());
    }

    @Override
    public void dispense() {
        //손잡이를 돌린 후 알맹이를 내보내야하므로 나갈 수 없는 상태.
        System.out.println("알맹이가 나갈 수 없습니다.");

    }

    @Override
    public void ejectQuarter() { //동전 없는 상태로
        System.out.println("동전이 반환됩니다.");
        gumballMachine.setState(gumballMachine.getNoQuarterState());

    }
}

상태를 가지고 있는 클래스

public class GumballMachine {
    State soldOutState;
    State noQuarterState;
    State hasQuarterState;
    State soldState;
    State state; //현재 상태 저장
    int count = 0; //알맹이 갯수 저장

    public GumballMachine(int count) {
        this.soldOutState = new SoldOutState(this);
        this.noQuarterState = new NoQuarterState(this);
        this.hasQuarterState = new HasQuarterState(this);
        this.soldState = new SoldOutState(this);
        state = soldOutState;
        this.count = count;
        if(count > 0){
            state = noQuarterState;
        }
    }
    public void insertQuarter(){
        state.insertQuarter();
    }
    public void ejectQuarter(){
        state.ejectQuarter();
    }
    public void turnCrank(){
        state.turnCrank();
        state.dispense();
    }
    public void setState(State state){
        this.state = state;
    }
    public void releaseBall() {
        System.out.println("A gumball comes rolling out the slot...");
        if (count != 0) {
            count -= 1;
        }
    }

//상태에 대한 getter 
...

}
profile
💻 ☕️ 🏝 🍑 🍹 🏊‍♀️

0개의 댓글