Writing /volume1/Web/Public/dokuwiki/data/log/deprecated/2024-11-15.log failed
差分
このページの2つのバージョン間の差分を表示します。
次のリビジョン | 前のリビジョン | ||
study:java:design_pattern:state [2008/09/20 04:31] – created banana | study:java:design_pattern:state [2010/10/16 02:09] (現在) – banana | ||
---|---|---|---|
行 16: | 行 16: | ||
자, 그럼 스테이트 패턴 클래스 다이어그램을 살펴볼까요? | 자, 그럼 스테이트 패턴 클래스 다이어그램을 살펴볼까요? | ||
+ | |||
+ | |||
===== Class Diagram ===== | ===== Class Diagram ===== | ||
{{: | {{: | ||
+ | |||
+ | 클래스 다이어그램을 살펴보면 어디서 본 것 같지 않나요? 맞습니다. 스트래티지 패턴과 모양이 비슷합니다. | ||
+ | 하지만 이 두 패턴은 용도에 있어서 차이가 있습니다. | ||
+ | |||
+ | 스테이트 패턴을 사용할 때는 상태 객체에 일련의 행동이 캡슐화됩니다. 상황에 따라 Context 객체에서 | ||
+ | 여러 상태 객체 중 한 객체에게 모든 행동을 맡기게 되죠. 그 객체의 내부 상태에 따라 현재 상태를 | ||
+ | 나타내는 객체가 바뀌게 되고, 그 결과로 컨텍스트 객체의 행동도 자연스럽게 바뀌게 됩니다. 클라이언트 | ||
+ | 는 상태 객체에 대해서 거의 아무것도 몰라도 됩니다. | ||
+ | |||
+ | 하지만 스트래티지 패턴을 사용할 때는 일반적으로 클라이언트에서 컨텍스트 객체한테 어떤 전략 객체를 | ||
+ | 사용할지를 지정해 줍니다. 스트래티지 패턴은 주로 실행시에 전략 객체를 변경할 수 있는 유연성을 제공 | ||
+ | 하기 위한 용도로 쓰이죠. 보통 가장 적합한 전략 객체를 선택해서 사용할게 됩니다. | ||
+ | |||
+ | 일반적으로 스트래티지 패턴은 서브클래스를 만드는 방법을 대신하여 유연성을 극대화하기 위한 용도로 쓰입니다. | ||
+ | 상속을 이용해서 클래스의 행동을 정의하다 보면 행동을 변경해야 할 때 마음대로 변경하기가 힘들죠. 하지만 | ||
+ | 스트래티지 패턴을 사용하면 구성을 통해 행동을 정의하는 객체를 유연하게 바꿀 수 있습니다. | ||
+ | |||
+ | 스테이트 패턴은 컨텍스트 객체에 수많은 조건문을 집어넣는 대신에 사용할 수 있는 패턴이라고 생각하면 됩니다. | ||
+ | 행동을 상태 객체 내에 캡슐화시키면 컨텍스트 내의 상태 객체를 바꾸는 것만으로도 컨텍스트 객체의 행동을 | ||
+ | 바꿀 수 있으니까요. | ||
+ | |||
+ | |||
+ | |||
+ | ===== Example ===== | ||
+ | 스테이트 패턴을 적용한 예로 뽑기 기계(%%Gumball Machine%%)를 살펴보겠습니다. | ||
+ | 먼저 클래스 다이어그램을 살펴볼까요? | ||
+ | {{: | ||
+ | |||
+ | 스테이트 패턴 클래스 다이어그램에서 Context에 해당하는 것이 %%GumballMachine%% 클래스입니다. | ||
+ | |||
+ | |||
+ | ===== GumballMachine Class ===== | ||
+ | <code java> | ||
+ | public class GumballMachine { | ||
+ | State soldOutState; | ||
+ | State noQuarterState; | ||
+ | State hasQuarterState; | ||
+ | State soldState; | ||
+ | State winnerState; | ||
+ | |||
+ | State state = soldOutState; | ||
+ | int count = 0; | ||
+ | |||
+ | public GumballMachine(int numberGumballs) { | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | if (numberGumballs > 0) { | ||
+ | state = noQuarterState; | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | public void insertQuarter(){ | ||
+ | state.insertQuarter(); | ||
+ | } | ||
+ | | ||
+ | public void ejectQuarter() { | ||
+ | state.ejectQuarter(); | ||
+ | } | ||
+ | |||
+ | public void turnCrank() { | ||
+ | state.turnCrank(); | ||
+ | state.dispense(); | ||
+ | } | ||
+ | |||
+ | void setState(State state) { | ||
+ | this.state = state; | ||
+ | } | ||
+ | |||
+ | void releaseBall() { | ||
+ | System.out.println(" | ||
+ | if (count != 0) { | ||
+ | count = count -1; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | public int getCount() { | ||
+ | return this.count; | ||
+ | } | ||
+ | |||
+ | public State getSoldOutState() { | ||
+ | return soldOutState; | ||
+ | } | ||
+ | |||
+ | public State getNoQuarterState() { | ||
+ | return noQuarterState; | ||
+ | } | ||
+ | |||
+ | public State getHasQuarterState() { | ||
+ | return hasQuarterState; | ||
+ | } | ||
+ | |||
+ | public State getSoldState() { | ||
+ | return soldState; | ||
+ | } | ||
+ | |||
+ | public State getWinnerState() { | ||
+ | return winnerState; | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ===== NoQuarterState Calss ===== | ||
+ | 상태를 구현해 볼 때가 되었습니다. 우선 **%%NoQuarterState%%**부터 시작해 봅시다. | ||
+ | <code java> | ||
+ | public class NoQuarterState implements State { | ||
+ | GumballMachine gumballMachine; | ||
+ | |||
+ | public NoQuraterState(GumballMachine gumballMachine) { | ||
+ | this.gumballMachine = gumballMachine; | ||
+ | } | ||
+ | |||
+ | public void insertQuarter() { | ||
+ | System.out.println(" | ||
+ | gumballMachine.setState(gumballMachine.getHasQuarterState()); | ||
+ | } | ||
+ | |||
+ | public void ejectQuarter() { | ||
+ | System.out.println(" | ||
+ | } | ||
+ | |||
+ | public void turnCrank() { | ||
+ | System.out.println(" | ||
+ | } | ||
+ | |||
+ | public void dispense() { | ||
+ | System.out.println(" | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | ===== HasQuarterState Class ===== | ||
+ | 이제 **%%GumballMachine%%** 클래스하고 상태 클래스가 어떤 식으로 맞물려 돌아가는지 어느 정도 | ||
+ | 감히 잡힐 것 같군요. 그럼 **%%HasQuarterState%%**와 **%%SoldSate%%** 클래스도 구현해 볼까요? | ||
+ | <code java> | ||
+ | public class HasQuarterState implements State { | ||
+ | | ||
+ | | ||
+ | |||
+ | | ||
+ | this.gumballMachine = gumballMachine; | ||
+ | } | ||
+ | |||
+ | | ||
+ | System.out.println(" | ||
+ | } | ||
+ | |||
+ | | ||
+ | System.out.println(" | ||
+ | gumballMachine.setState(gumballMachie.getNoQuarterState()); | ||
+ | } | ||
+ | |||
+ | | ||
+ | System.out.println(" | ||
+ | int winner = randomWinner.nextInt(10); | ||
+ | if((winner==0) && (gumballMachine.getCount() > 1)) { | ||
+ | | ||
+ | } else { | ||
+ | | ||
+ | } | ||
+ | } | ||
+ | |||
+ | | ||
+ | System.out.println(" | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | ===== SoldState Class ===== | ||
+ | **%%SolidState%%** 클래스도 살펴봅시다. | ||
+ | <code java> | ||
+ | public class SolidState implements State { | ||
+ | | ||
+ | |||
+ | | ||
+ | | ||
+ | } | ||
+ | |||
+ | | ||
+ | | ||
+ | } | ||
+ | |||
+ | | ||
+ | | ||
+ | } | ||
+ | |||
+ | | ||
+ | | ||
+ | } | ||
+ | |||
+ | | ||
+ | | ||
+ | if (gumballMachine.getCount() > 0) { | ||
+ | | ||
+ | } else { | ||
+ | | ||
+ | | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | ===== SoldOutState Class ===== | ||
+ | <code java> | ||
+ | public class SoldOutState implements State { | ||
+ | GumballMachine gumballMachine; | ||
+ | |||
+ | public SoldOutState(GumballMachine gumballMachine) { | ||
+ | | ||
+ | } | ||
+ | |||
+ | public void insertQuarter() { | ||
+ | | ||
+ | } | ||
+ | |||
+ | public void ejectQuarter() { | ||
+ | | ||
+ | } | ||
+ | |||
+ | public void turnCrank() { | ||
+ | | ||
+ | } | ||
+ | |||
+ | public void dispense() { | ||
+ | | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | ===== WinnerState Class ===== | ||
+ | <code java> | ||
+ | public class WinnerState implements State { | ||
+ | | ||
+ | |||
+ | | ||
+ | | ||
+ | } | ||
+ | |||
+ | | ||
+ | | ||
+ | } | ||
+ | |||
+ | | ||
+ | | ||
+ | } | ||
+ | |||
+ | | ||
+ | | ||
+ | } | ||
+ | |||
+ | | ||
+ | | ||
+ | | ||
+ | if (gumballMachine.getCount() == 0) { | ||
+ | | ||
+ | } else { | ||
+ | | ||
+ | | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </ | ||