狀态模式定義,允許對象在自己内部狀态改變時改變它的行為,對象看起來就像是修改了它的類。
該描述第一部分意思是,這個模式将狀态封裝進了一個獨立的類,并将動作委托到對象的目前狀态的狀态對象。第二個部分意思就是,讓客戶感覺使用了對象能夠改變它的行為,但是實際上這種設計模式 使用組合通過簡單引用不同狀态對象來造成類的改變假象。狀态模式封裝了一組行為。
狀态模式類圖
Context:是一個上下文類,可以擁有一些内部狀态,并且将多個狀态對象組合結合在一起。
State接口:定義了所有狀态具有的共同操作,一般可以将該接口的方法和context設定一樣的。
ConcreteStateA:實作了具體的狀态對象,處理來自context的請求,凡是context中調用request方法,都會将該方法委托到具體的狀态對象來處理。
通過在context來利用組合和多态,進而在實際的狀态改變中将行為委托到具體的實作狀态類中,狀态模式将每一個狀态的行為具體到局部化到該狀态所對象的類中,免去了大量的if判斷,它可以讓每一個狀态“對修改關閉”,讓context“對擴充開放”。
一般來說,當狀态轉換是固定的時候,一般将狀态的改變放置到context中。當轉換是動态的時候,則将狀态的改變放置到狀态類中,狀态類中應該有context的引用。
執行個體代碼
一個糖果機,有四種不同的狀态,根據不同的行為就會轉換成不同的狀态。
狀态State接口
package com.whut.state;
publicinterface State {
void insertQuarter();
void ejectQuarter();
void turnCrank();
void dispense();
}
糖果機類(context)
//狀态模式
public class GumballMachine {
private State soleOutState;
private State noQuarterState;
private State hasQuarterState;
private State soldState;
private State winnerState;
private State state=soleOutState;
private int count=0;
public GumballMachine(int count)
{
soleOutState=new SoldOutState(this);
noQuarterState=new NoQuarterState(this);
hasQuarterState=new HasQuarterState(this);
soldState=new SoldState(this);
winnerState=new WinnerState(this);
this.count=count;
if(count>0)
state=noQuarterState;
//投入25分的動作
public void insertQuarter()
state.insertQuarter();
//退回25分的動作
public void ejectQuarter()
state.ejectQuarter();
//轉動曲柄
public void turnCrank()
state.turnCrank();
state.dispense();
//釋放糖果
public void releaseBall()
System.out.println("A gunmball comes rolling out the slot from machine");
if(count!=0)
count=count-1;
//列印機器目前狀态
@Override
public String toString()
return"-----------"+"\nThe machine state:"+state.toString()+"\ncount="+count+"\n-----------";
//設定狀态
publicvoid setState(State st)
this.state=st;
//擷取狀态
public State getSoleOutState() {
return soleOutState;
public State getNoQuarterState() {
return noQuarterState;
public State getHasQuarterState() {
return hasQuarterState;
public State getSoldState() {
return soldState;
//擷取總的數目
publicint getCount() {
return count;
public State getWinnerState() {
return winnerState;
狀态實作類:
public class NoQuarterState implements State {
private GumballMachine gumballMachine;
public NoQuarterState(GumballMachine gumballMachine)
this.gumballMachine=gumballMachine;
publicvoid insertQuarter() {
System.out.println("You inserted a quarter");
gumballMachine.setState(gumballMachine.getHasQuarterState());
publicvoid ejectQuarter() {
System.out.println("You haven't inserted a quarter");
publicvoid turnCrank() {
System.out.println("You turned,but there's no quarter");
publicvoid dispense() {
System.out.println("You need to pay a quarter first");
狀态模式與政策模式比較
狀态模式,将一群行為封裝到狀态對象中,Context的行為随時可委托到那些狀态對象中的一個。對象的狀态改變是在内部實作的,遊走于對象集合中,使用者察覺不到,隻是通過觸發相應的行為。狀态模式利用許多個不同的狀态對象作為其成員屬性進行組合,任何狀态的改變都是事先定義好的。
政策模式,客戶往往是主動指定Context所要組合的政策對象是哪一個,使得能夠在運作的時候改變政策即對象的行為。可以将狀态模式想成是不用在context中放置許多條件判斷語句的替代方法,通過将行為包裝進狀态對象後,可以通過在context内部來改變狀态對象來改變context的行為。政策模式通常是利用行為或者政策類來配置context類的。
本文轉自 zhao_xiao_long 51CTO部落格,原文連結:http://blog.51cto.com/computerdragon/1177995