1) 의미 및 구현방법
현재 상태에 따라 다른 동작을 보일때 if 구문으로 처리하면
됩니다.
그 if 구문의 원인이 되는 상태값이나 상태 기준이 계속 바뀐다면
그땐 if 구문이 계속 뜯어고쳐지는 상태가 반복됩니다.
이때 state 패턴으로 해당 if 구문을 치환 가능합니다.
의미상 이렇지만 실제 생김새를 보면 스트레이트 패턴과 거의
일치합니다.
2) 참고자료
http://hongjinhyeon.tistory.com/50
2. 소스
1) state 인터페이스 작성
해당 인터페이스가 각 상태를 정의함
package stateI; public interface State { public void insertQuarter(); public void ejectQuarter(); public void turnCrank(); public void dispense(); }
2) state를 implements 한 각 상태 관련 객체들
package stats; import instances.GumballMachine; import stateI.State; public class HasQuarterState implements State { transient GumballMachine gumballMachine; public HasQuarterState(GumballMachine gumballMachine){ this.gumballMachine=gumballMachine; } @Override public void insertQuarter() { System.out.println("You can't insert another quarter"); } @Override public void ejectQuarter() { System.out.println("Quarter returned"); gumballMachine.setState(gumballMachine.getNoQuarterState()); } @Override public void turnCrank() { System.out.println("You turned..."); gumballMachine.setState(gumballMachine.getSoldState()); } @Override public void dispense() { // TODO Auto-generated method stub System.out.println("No gumball dispensed"); } }
package stats; import instances.GumballMachine; import stateI.State; public class NoQuarterState implements State { GumballMachine gumballMachine; public NoQuarterState(GumballMachine gumballMachine){ this.gumballMachine=gumballMachine; } @Override public void insertQuarter() { System.out.println("you are insert coin"); gumballMachine.setState(gumballMachine.getHasQuarterState()); } @Override public void ejectQuarter() { System.out.println("please insert coin"); } @Override public void turnCrank() { System.out.println("please insert coin"); } @Override public void dispense() { System.out.println("please insert coin"); } }
package stats; import instances.GumballMachine; import stateI.State; public class SoldOutState implements State { transient GumballMachine gumballMachine; public SoldOutState(GumballMachine gumballMachine) { this.gumballMachine = gumballMachine; } @Override public void insertQuarter() { // TODO Auto-generated method stub System.out.println("You can't insert a quarter, the machine is sold out"); } @Override public void ejectQuarter() { // TODO Auto-generated method stub System.out.println("You can't eject, you haven't inserted a quarter yet"); } @Override public void turnCrank() { // TODO Auto-generated method stub System.out.println("You turned, but there are no gumballs"); } @Override public void dispense() { // TODO Auto-generated method stub System.out.println("No gumball dispensed"); } }
package stats; import instances.GumballMachine; import stateI.State; public class SoldState implements State{ transient GumballMachine gumballMachine; public SoldState(GumballMachine gumballMachine) { this.gumballMachine = gumballMachine; } @Override public void insertQuarter() { // TODO Auto-generated method stub System.out.println("this give you egg ....ing"); } @Override public void ejectQuarter() { // TODO Auto-generated method stub System.out.println("you alrealy take it"); } @Override public void turnCrank() { // TODO Auto-generated method stub System.out.println("try only one!"); } @Override public void dispense() { gumballMachine.releaseBall(); if(gumballMachine.getCount()>0){ gumballMachine.setState(gumballMachine.getNoQuarterState()); }else{ System.out.println("Opps , out of gumballs"); gumballMachine.setState(gumballMachine.getSoldState()); } } }
3) state를 이용해 이를 구현한 구현체
package instances; import stateI.State; import stats.HasQuarterState; import stats.NoQuarterState; import stats.SoldOutState; import stats.SoldState; public class GumballMachine { State soldOutState; State noQuarterState; State hasQuarterState; State soldState; State state = soldOutState; int count =0; public GumballMachine(int numberGumballs){ soldOutState = new SoldOutState(this); noQuarterState = new NoQuarterState(this); hasQuarterState = new HasQuarterState(this); soldState = new SoldState(this); this.count =numberGumballs; if(numberGumballs>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=count -1; } } public void refill(int count) { this.count = count; state = noQuarterState; } public int getCount() { return count; } public State getState(){ return state; } public State getSoldOutState(){ return getSoldOutState(); } public State getNoQuarterState() { return noQuarterState; } public State getHasQuarterState() { return hasQuarterState; } public State getSoldState() { return soldState; } public String toString() { StringBuffer result = new StringBuffer(); result.append("\nMighty Gumball, Inc."); result.append("\nJava-enabled Standing Gumball Model #2004"); result.append("\nInventory: " + count + " gumball"); if (count != 1) { result.append("s"); } result.append("\n"); result.append("Machine is " + state + "\n"); return result.toString(); } }
4) 이를 테스트 하기 위한 코드
package tsstmain; import instances.GumballMachine; 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 stats.NoQuarterState@2d11f5f1
you are insert coin
You turned...
A gumball comes rolling out the slot...
Mighty Gumball, Inc.
Java-enabled Standing Gumball Model #2004
Inventory: 4 gumballs
Machine is stats.NoQuarterState@2d11f5f1
you are insert coin
You turned...
A gumball comes rolling out the slot...
you are insert coin
You turned...
A gumball comes rolling out the slot...
Mighty Gumball, Inc.
Java-enabled Standing Gumball Model #2004
Inventory: 2 gumballs
Machine is stats.NoQuarterState@2d11f5f1
2. 다이어그램
3) 다이어그램
역시 하단 링크를 참고바랍니다.
하단 링크에서도 자세하게 설명하고 있습니다.
state 및 이를 implements 한 구현체 클래스는 스트리티지
패턴과 비슷하나 이를 밖에서 조합하여
쓰는 과정에서 약간 차이가 있음.
http://hongjinhyeon.tistory.com/50
댓글 없음:
댓글 쓰기