classDiagram
direction TB
class Context {
+request()
+setState(State state)
}
class State {
<<interface>>
+handle(Context context)
}
class ConcreteStateA {
+handle(Context context)
}
class ConcreteStateB {
+handle(Context context)
}
Context --> State : 当前状态
State <|.. ConcreteStateA
State <|.. ConcreteStateB
State ..> Context : 请求状态切换
stateDiagram-v2
direction LR
state InitialStock <<choice>>
state "没有25分钱" as NoQuarter
state "有25分钱" as HasQuarter
state "售出糖果" as Sold
state "糖果售罄" as SoldOut
[*] --> InitialStock
InitialStock --> NoQuarter: 初始库存大于0
InitialStock --> SoldOut: 初始库存为0
NoQuarter --> HasQuarter: 投入25分钱
HasQuarter --> NoQuarter: 退回25分钱
HasQuarter --> Sold: 转动曲柄
Sold --> NoQuarter: 发放糖果,仍有库存
Sold --> SoldOut: 发放最后一颗糖果
publicvoidinsertQuarter(){if(state==HAS_QUARTER){System.out.println("You can't insert another quarter");}elseif(state==SOLD_OUT){System.out.println("You can't insert a quarter, the machine is sold out");}elseif(state==SOLD){System.out.println("Please wait,we're already giving you a gumball");}elseif(state==NO_QUARTER){state=HAS_QUARTER;System.out.println("You inserted a quarter");}}
publicclassGumballMachine{finalstaticintSOLD_OUT=0;//售罄finalstaticintNO_QUARTER=1;finalstaticintHAS_QUARTER=2;finalstaticintSOLD=3;//售出intstate=SOLD_OUT;//当前状态intcount=0;publicGumballMachine(intcount){this.count=count;if(count>0){state=NO_QUARTER;}}//当有25分钱投进来,就会执行这里...publicvoidinsertQuarter(){if(state==HAS_QUARTER){System.out.println("You can't insert another quarter");}elseif(state==SOLD_OUT){System.out.println("You can't insert a quarter, the machine is sold out");}elseif(state==SOLD){System.out.println("Please wait,we're already giving you a gumball");}elseif(state==NO_QUARTER){System.out.println("You inserted a quarter");state=HAS_QUARTER;}}//现在,如果顾客试着退回25分钱publicvoidejectQuarter(){if(state==HAS_QUARTER){//如果有25分钱,就把钱退回来,回到没有25分钱的状态。System.out.println("Quarter returned");state=NO_QUARTER;}elseif(state==SOLD_OUT){//如果没有25分钱的话,当然不能退回25分钱System.out.println("You haven't inserted a quarter");}elseif(state==SOLD){//如果顾客已经转动曲柄,就不能在退钱了,他已经拿到糖果了System.out.println("Sorry,you already turned the crank");}elseif(state==NO_QUARTER){//如果糖果售罄,就不可能接受25分钱,当然也不可能退钱。System.out.println("You can't eject,you haven't inserted a quarter yet");}}//顾客试着转动曲柄publicvoidturnCrank(){if(state==SOLD){System.out.println("Turning twice doesn't get you another gumball!");}elseif(state==NO_QUARTER){//System.out.println("You turned but there's no quarter");}elseif(state==SOLD_OUT){System.out.println("You turned,but there are no gumballs");}elseif(state==HAS_QUARTER){System.out.println("You turned...");state=SOLD;dispense();}}//调用此方法发放糖果publicvoiddispense(){if(state==SOLD){System.out.println("A gumball comes rolling out the slot");count=count-1;if(count==0){System.out.println("Oops, out of gumballs!");state=SOLD_OUT;}else{state=NO_QUARTER;}}elseif(state==NO_QUARTER){System.out.println("You need to pay first");}elseif(state==SOLD_OUT){System.out.println("No gumball dispensed");}elseif(state==HAS_QUARTER){System.out.println("No gumball dispensed");}}publicvoidrefill(intnumGumBalls){this.count=numGumBalls;state=NO_QUARTER;}publicStringtoString(){StringBufferresult=newStringBuffer();result.append("\nMighty Gumball, Inc.");result.append("\nJava-enabled Standing Gumball Model #2004\n");result.append("Inventory: "+count+" gumball");if(count!=1){result.append("s");}result.append("\nMachine is ");if(state==SOLD_OUT){result.append("sold out");}elseif(state==NO_QUARTER){result.append("waiting for quarter");}elseif(state==HAS_QUARTER){result.append("waiting for turn of crank");}elseif(state==SOLD){result.append("delivering a gumball");}result.append("\n");returnresult.toString();}}
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
Quarter returned
You turned but there's no quarter
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
You can't eject,you haven't inserted a quarter yet
Mighty Gumball, Inc.
Java-enabled Standing Gumball Model #2004
Inventory: 2 gumballs
Machine is waiting for quarter
You inserted a quarter
You can't insert another quarter
You turned...
A gumball comes rolling out the slot
You inserted a quarter
You turned...
A gumball comes rolling out the slot
Oops, out of gumballs!
You can't insert a quarter, the machine is sold out
You turned,but there are no gumballs
Mighty Gumball, Inc.
Java-enabled Standing Gumball Model #2004
Inventory: 0 gumballs
Machine is sold out
classDiagram
direction TB
class State {
<<interface>>
+insertQuarter()
+ejectQuarter()
+turnCrank()
+dispense()
}
class WinnerState {
+insertQuarter()
+ejectQuarter()
+turnCrank()
+dispense()
}
State <|.. WinnerState
publicclassNoQuarterStateimplementsState{GumballMachinegumballMachine;publicNoQuarterState(GumballMachinegumballMachine){this.gumballMachine=gumballMachine;}publicvoidinsertQuarter(){System.out.println("You inserted a quarter");gumballMachine.setState(gumballMachine.getHasQuarterState());}publicvoidejectQuarter(){System.out.println("You haven't inserted a quarter");}publicvoidturnCrank(){System.out.println("You turned, but there's no quarter");}publicvoiddispense(){System.out.println("You need to pay first");}publicvoidrefill(){}publicStringtoString(){return"waiting for quarter";}}publicclassHasQuarterStateimplementsState{GumballMachinegumballMachine;publicHasQuarterState(GumballMachinegumballMachine){this.gumballMachine=gumballMachine;}publicvoidinsertQuarter(){System.out.println("You can't insert another quarter");}publicvoidejectQuarter(){System.out.println("Quarter returned");gumballMachine.setState(gumballMachine.getNoQuarterState());}publicvoidturnCrank(){System.out.println("You turned...");gumballMachine.setState(gumballMachine.getSoldState());}publicvoiddispense(){System.out.println("No gumball dispensed");}publicvoidrefill(){}publicStringtoString(){return"waiting for turn of crank";}}publicclassSoldOutStateimplementsState{GumballMachinegumballMachine;publicSoldOutState(GumballMachinegumballMachine){this.gumballMachine=gumballMachine;}publicvoidinsertQuarter(){System.out.println("You can't insert a quarter, the machine is sold out");}publicvoidejectQuarter(){System.out.println("You can't eject, you haven't inserted a quarter yet");}publicvoidturnCrank(){System.out.println("You turned, but there are no gumballs");}publicvoiddispense(){System.out.println("No gumball dispensed");}publicvoidrefill(){gumballMachine.setState(gumballMachine.getNoQuarterState());}publicStringtoString(){return"sold out";}}publicclassSoldStateimplementsState{GumballMachinegumballMachine;publicSoldState(GumballMachinegumballMachine){this.gumballMachine=gumballMachine;}publicvoidinsertQuarter(){System.out.println("Please wait, we're already giving you a gumball");}publicvoidejectQuarter(){System.out.println("Sorry, you already turned the crank");}publicvoidturnCrank(){System.out.println("Turning twice doesn't get you another gumball!");}publicvoiddispense(){gumballMachine.releaseBall();if(gumballMachine.getCount()>0){gumballMachine.setState(gumballMachine.getNoQuarterState());}else{System.out.println("Oops, out of gumballs!");gumballMachine.setState(gumballMachine.getSoldOutState());}}publicvoidrefill(){}publicStringtoString(){return"dispensing a gumball";}}
publicclassGumballMachine{StatesoldOutState;StatenoQuarterState;StatehasQuarterState;StatesoldState;Statestate;intcount=0;publicGumballMachine(intnumberGumballs){soldOutState=newSoldOutState(this);noQuarterState=newNoQuarterState(this);hasQuarterState=newHasQuarterState(this);soldState=newSoldState(this);this.count=numberGumballs;if(numberGumballs>0){state=noQuarterState;}else{state=soldOutState;}}publicvoidinsertQuarter(){state.insertQuarter();}publicvoidejectQuarter(){state.ejectQuarter();}publicvoidturnCrank(){state.turnCrank();state.dispense();}voidreleaseBall(){System.out.println("A gumball comes rolling out the slot...");if(count!=0){count=count-1;}}intgetCount(){returncount;}voidrefill(intcount){this.count+=count;System.out.println("The gumball machine was just refilled; it's new count is: "+this.count);state.refill();}voidsetState(Statestate){this.state=state;}publicStategetState(){returnstate;}publicStategetSoldOutState(){returnsoldOutState;}publicStategetNoQuarterState(){returnnoQuarterState;}publicStategetHasQuarterState(){returnhasQuarterState;}publicStategetSoldState(){returnsoldState;}publicStringtoString(){StringBufferresult=newStringBuffer();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");returnresult.toString();}}
publicclassWinnerStateimplementsState{GumballMachinegumballMachine;publicWinnerState(GumballMachinegumballMachine){this.gumballMachine=gumballMachine;}publicvoidinsertQuarter(){System.out.println("Please wait, we're already giving you a Gumball");}publicvoidejectQuarter(){System.out.println("Please wait, we're already giving you a Gumball");}publicvoidturnCrank(){System.out.println("Turning again doesn't get you another gumball!");}publicvoiddispense(){gumballMachine.releaseBall();if(gumballMachine.getCount()==0){gumballMachine.setState(gumballMachine.getSoldOutState());}else{gumballMachine.releaseBall();System.out.println("YOU'RE A WINNER! You got two gumballs for your quarter");if(gumballMachine.getCount()>0){gumballMachine.setState(gumballMachine.getNoQuarterState());}else{System.out.println("Oops, out of gumballs!");gumballMachine.setState(gumballMachine.getSoldOutState());}}}publicvoidrefill(){}publicStringtoString(){return"despensing two gumballs for your quarter, because YOU'RE A WINNER!";}}publicclassGumballMachine{StatesoldOutState;StatenoQuarterState;StatehasQuarterState;StatesoldState;StatewinnerState;//加进一个新的WinnerState状态,然后在构造器中将它初始化//...}publicclassHasQuarterStateimplementsState{RandomrandomWinner=newRandom(System.currentTimeMillis());GumballMachinegumballMachine;publicHasQuarterState(GumballMachinegumballMachine){this.gumballMachine=gumballMachine;}publicvoidinsertQuarter(){System.out.println("You can't insert another quarter");}publicvoidejectQuarter(){System.out.println("Quarter returned");gumballMachine.setState(gumballMachine.getNoQuarterState());}publicvoidturnCrank(){System.out.println("You turned...");intwinner=randomWinner.nextInt(10);if((winner==0)&&(gumballMachine.getCount()>1)){gumballMachine.setState(gumballMachine.getWinnerState());}else{gumballMachine.setState(gumballMachine.getSoldState());}}publicvoiddispense(){System.out.println("No gumball dispensed");}publicvoidrefill(){}publicStringtoString(){return"waiting for turn of crank";}}publicclassGumballMachineTestDrive{publicstaticvoidmain(String[]args){GumballMachinegumballMachine=newGumballMachine(10);System.out.println(gumballMachine);gumballMachine.insertQuarter();gumballMachine.turnCrank();gumballMachine.insertQuarter();gumballMachine.turnCrank();System.out.println(gumballMachine);gumballMachine.insertQuarter();gumballMachine.turnCrank();gumballMachine.insertQuarter();gumballMachine.turnCrank();System.out.println(gumballMachine);gumballMachine.insertQuarter();gumballMachine.turnCrank();gumballMachine.insertQuarter();gumballMachine.turnCrank();System.out.println(gumballMachine);gumballMachine.insertQuarter();gumballMachine.turnCrank();gumballMachine.insertQuarter();gumballMachine.turnCrank();System.out.println(gumballMachine);gumballMachine.insertQuarter();gumballMachine.turnCrank();gumballMachine.insertQuarter();gumballMachine.turnCrank();System.out.println(gumballMachine);}}
classDiagram
direction TB
class GumballMachine {
State state
int count
+insertQuarter()
+ejectQuarter()
+turnCrank()
setState(State state)
releaseBall()
refill(int count)
}
class State {
<<interface>>
+insertQuarter()
+ejectQuarter()
+turnCrank()
+dispense()
+refill()
}
class NoQuarterState
class HasQuarterState
class SoldState
class WinnerState
class SoldOutState
GumballMachine --> State : 当前状态
State <|.. NoQuarterState
State <|.. HasQuarterState
State <|.. SoldState
State <|.. WinnerState
State <|.. SoldOutState
HasQuarterState --> GumballMachine : 查询库存并切换
WinnerState --> GumballMachine : 发放奖励并切换