定義
允許對(duì)象在內(nèi)部轉(zhuǎn)態(tài)改變時(shí)改變它的行為,對(duì)象看起來(lái)好像修改了它的類。
使用場(chǎng)景
- 對(duì)象的行為取決于它的狀態(tài),并且它會(huì)在運(yùn)行時(shí)根據(jù)狀態(tài)改變行為
- 大量的操作會(huì)引入很多依賴對(duì)象狀態(tài)的條件語(yǔ)句,對(duì)象的狀態(tài)可由一個(gè)或多個(gè)枚舉常量表示,并且許多操作通常包含相同的條件結(jié)構(gòu)。 狀態(tài)模式將每個(gè)條件分支放在單獨(dú)的類中。 這使我們可以將對(duì)象的狀態(tài)視為一個(gè)對(duì)象,而且此對(duì)象可以獨(dú)立于其他對(duì)象進(jìn)行變化。
例子
如下是一個(gè)糖果販賣機(jī)的狀態(tài)轉(zhuǎn)換圖,投入0.25元轉(zhuǎn)動(dòng)曲柄可以獲得糖果。
Paste_Image.png
首先定義各種狀態(tài),并且實(shí)現(xiàn)各種狀態(tài)的方法,如投幣、拿回幣、轉(zhuǎn)動(dòng)曲柄、分發(fā)糖果;有些狀態(tài)的方法其實(shí)是無(wú)效的:
public interface State{
public void insertQuarter();
public void ejectQuarter();
public void turnCrank();
public void dispense();
}
// 投入硬幣的狀態(tài)
public class HasQuarterState implements State{
GumballMachine gumballMachine;
public HasQuarterState(GumballMachine gumballMachine){
this.gumballMachine = gumballMachine;
}
public void insertQuarter(){
System.out.println("You can not insert another quarter");
}
public void ejectQuarter(){
System.out.println("Quarter returned");
gumballMachine.setState(gumballMachine.getNoQuarterState());
}
public void turnCrank(){ // 搖動(dòng)曲柄
System.out.println("You turned...");
gumballMachine.setState(gumballMachine.getSoldState());
}
public void dispense(){
System.out.println(" No gumball dispensed");
}
}
// 轉(zhuǎn)動(dòng)曲柄 銷售狀態(tài)
public class SoldState implements State{
GumballMachine gumballMachine;
public SoldState(GumballMachine gumballMachine){
this.gumballMachine = gumballMachine;
}
public void insertQuarter(){
System.out.println("Please wait, we are already giving you a gumball");
}
public void ejectQuarter(){
System.out.println("Sorry, you have turned the crank");
}
public void turnCrank(){ // 搖動(dòng)曲柄
System.out.println("Turing twice doesn't get you another gumball");
}
public void dispense(){
gumballMachine.releaseBall();
if(gumballMachine.getCount() > 0){
gumballMachine.setState(gumballMachine.getNoQuarterState());
}else{
System.out.println("out of gumballs");
gumballMachine.setState(gumballMachine.getSoldOutState());
}
}
}
// NoQuarterState SoldOutState
糖果機(jī)的實(shí)現(xiàn):
public class GumballMachine{
State soldOutState;
State noQuarterState;
State hasQuarterState;
State soldState;
State state = soldState;
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();
}
void setState(State state){
this.state = state;
}
void releaseBall(){
System.out.println("A gumball comes rolling out the slot...");
if(count !=0 ){
count = count-1;
}
}
// getNoQuarterState等各種getter
}
分析
狀態(tài)模式:封裝基于狀態(tài)的行為,并將行為委托到當(dāng)前狀態(tài)。
策略模式:將可以互換的行為封裝起來(lái),然后使用委托的方法決定使用哪一個(gè)行為