State 패턴

Java Design Pattern 2013. 2. 22. 06:00

객체의 내부상태가 변경됨에 따라서 객체의 행동을 바꿀 있다. 마치 객체의 클래스가 바뀌는 것과 같은 결과를 얻을 있다.

 

시나리오

 

    뽑기 기계의 상태 

 

뽑기 기계를 가정했을때 뽑기 기계의 상태를 다음과 같이 정리해 있다.

        -  알맹이 매진상태

        -  동전있음

        -  동전없음

        -  알맨이 판매

기계의 코드에 상태코드를 두어 행위(insertCoin(), ejectQuartar(), turnCrank()…)에서 각각의 상태코드를 체크하게되면 복잡한 if문이 구성되면서 행위 분리 원칙에도 위배된다.

 

다음과 같은코드가 행위를 제어하는 메소드 마드 들어가게 된다.

public void insertQuarter() {

              if (state == HAS_QUARTER) {

                     System.out.println("You can't insert~~~");

              } else if (state == NO_QUARTER) {

                     state = HAS_QUARTER;

                     System.out.println("You inserted a quarter~~");

              } else if (state == SOLD_OUT) {

                     System.out.println("You can't insert a quarter,~~~");

              } else if (state == SOLD) {

                     System.out.println("Please wait, we're already~~");

              }

}

à 대안책으로

                상태객체들을 별도의 코드로 구성하고 어떠한 행동일 일어나면 현재상태의 객체에서 필요한 작업을 처리하게 하는 것이다.

 

 

다음은 각각의 상태를 모델링하고 State 인터페이스와 NoQuartarState 대한 코드이다.

 

 

 

package headfirst.state.gumballstate;

 

public interface State {

 

       public void insertQuarter();

       public void ejectQuarter();

       public void turnCrank();

       public void dispense();

}

 

 

 

package headfirst.state.gumballstate;

 

public class NoQuarterState implements State {

       GumballMachine gumballMachine;

 

       /**

        * 생성자를 통해서 뽑기기계에대한 레퍼런스가 전달된다.

        * @param gumballMachine

        */

       public NoQuarterState(GumballMachine gumballMachine) {

              this.gumballMachine = gumballMachine;

       }

 

       /* NoQuarter 상태에서 동전을 넣게되면 이미 동전이 있다는 메시지를 출력하고

        * 뽑기 기계의레퍼런스를 다른 객체의 상태로 바꿈으로써 다음 상태로 전환된다.

        * @see headfirst.state.gumballstate.State#insertQuarter()

        */

       public void insertQuarter() {

              System.out.println("You inserted a quarter");

              gumballMachine.setState(gumballMachine.getHasQuarterState());

       }

 

       public void ejectQuarter() {

              System.out.println("You haven't inserted a quarter");

       }

 

       public void turnCrank() {

              System.out.println("You turned, but there's no quarter");

       }

 

       public void dispense() {

              System.out.println("You need to pay first");

       }

 

       public String toString() {

              return "waiting for quarter";

       }

}

 

 

 

상태의 전환은 State클래스에 의해 제어할 수도 있고, Context클래스에 의해서 제어할 수도 있다.

 

 

객체의 내부상태가 변경됨에 따라서 객체의 행동을 바꿀 있다. 마치 객체의 클래스가 바뀌는 것과 같은 결과를 얻을 있으며 Context 객체(GumballMachine) 해당 상태에대한 행동의 책임을 해당 상태클래스에게 위임한다.

 

다음은 상태제어 테스트 클래스이다.

 

package headfirst.state.gumballstate;

 

public class GumballMachineTestDrive {

 

       public static void main(String[] args) {

              // 뽑기 알맹이의 개수를 초기화 한다.

              GumballMachine gumballMachine = new GumballMachine(5);

 

              System.out.println(gumballMachine);

 

              gumballMachine.insertQuarter();

              gumballMachine.turnCrank();

 

              System.out.println(gumballMachine);

 

              gumballMachine.insertQuarter();

              gumballMachine.turnCrank();

              gumballMachine.insertQuarter();

              gumballMachine.turnCrank();

 

              System.out.println(gumballMachine);

       }

}

 

 

  

실행결과

Mighty Gumball, Inc.

Java-enabled Standing Gumball Model #2004

Inventory: 5 gumballs

Machine is waiting for quarter

 

You inserted a quarter

You turned...

A gumball comes rolling out the slot...

 

Mighty Gumball, Inc.

Java-enabled Standing Gumball Model #2004

Inventory: 4 gumballs

Machine is waiting for quarter

 

You inserted a quarter

You turned...

A gumball comes rolling out the slot...

You inserted a quarter

You turned...

A gumball comes rolling out the slot...

 

Mighty Gumball, Inc.

Java-enabled Standing Gumball Model #2004

Inventory: 2 gumballs

Machine is waiting for quarter

 

  

 

소스코드 파일

 GumballMachine.javaGumballMachineTestDrive.javaHasQuarterState.javaNoQuarterState.javaSoldOutState.javaSoldState.javaState.java

 

 

'Java Design Pattern' 카테고리의 다른 글

디자인패턴의 분류  (0) 2013.02.22
Iterator 패턴 & Composite 패턴  (0) 2013.02.21
Template Method 패턴  (0) 2013.02.20
Factory 패턴  (0) 2013.02.20
Decorator 패턴  (0) 2013.02.20
Posted by Steven J.S Min
,