一、 State模式定義:
允許一個(gè)對象在其狀態(tài)改變時(shí),改變它的行為。看起來對象似乎修改了它的類。
二、 模式解說
State模式主要解決的是在開發(fā)中時(shí)常遇到的根據(jù)不同的狀態(tài)需要進(jìn)行不同的處理操作的問題,而這樣的問題,大部分人是采用switch-case語句進(jìn)行處理的,這樣會(huì)造成一個(gè)問題:分支過多,而且如果加入一個(gè)新的狀態(tài)就需要對原來的代碼進(jìn)行編譯。State模式采用了對這些不同的狀態(tài)進(jìn)行封裝的方式處理這類問題,當(dāng)狀態(tài)改變的時(shí)候進(jìn)行處理然后再切換到另一種狀態(tài),也就是說把狀態(tài)的切換責(zé)任交給了具體的狀態(tài)類去負(fù)責(zé).同時(shí),State模式和Strategy模式有很多相似的地方,需要說明的是兩者的思想都是一致的,只不過封裝的東西不同:State模式封裝的是不同的狀態(tài),而Stategy模式封裝的是不同的算法。
三、 結(jié)構(gòu)圖
State模式結(jié)構(gòu)圖如下:

四、 怎么使用?
1) 定義一個(gè)State接口,接口中有一個(gè)統(tǒng)一的方法,用以封裝一個(gè)特定狀態(tài)所對應(yīng)的行為。
2) 定義具體不同狀態(tài)類ConcreteSate實(shí)現(xiàn)State接口。
3) 每一個(gè)狀態(tài)類都實(shí)現(xiàn)環(huán)境(Context)一個(gè)狀態(tài)所對應(yīng)的行為。
4) 定義一個(gè)狀態(tài)管理器Context.
五、 一個(gè)例子
interface State{
public void handle(Context ctx);
}
class ConcreteStateA implements State{
public void handle(Context ctx) {
System.out.println("handle by ConcreteStateA");
if(ctx!=null){
ctx.ChangeState(new ConcreteStateB());
}
}
}
class ConcreteStateB implements State{
public void handle(Context ctx) {
System.out.println("handle by ConcreteStateB");
if(ctx!=null){
ctx.ChangeState(new ConcreteStateA());
}
}
}
class Context{
private State _state;
public Context(State state){
_state=state;
}
public void request(){
if(_state!=null){
_state.handle(this);
}
}
public void ChangeState(State s){
if(_state!=null){
_state=null;
}
_state=s;
}
}
public class StateClient {
public static void main(String[] args) {
State state=new ConcreteStateA();
Context context=new Context(state);
context.request();
context.request();
context.request();
context.request();
}
}
輸出結(jié)果:
handle by ConcreteStateA
handle by ConcreteStateB
handle by ConcreteStateA
handle by ConcreteStateB
每請求一次,狀態(tài)就更換一次,就執(zhí)行對應(yīng)的行為。
六、 適用性
1) 一個(gè)對象的行為取決于它的狀態(tài),并且它必須在運(yùn)行時(shí)刻根據(jù)狀態(tài)改變它的行為。
2) 一個(gè)對象含有龐大的條件分支語句,這些分支依賴于它的狀態(tài)。這個(gè)狀態(tài)通常用一個(gè)或多個(gè)枚舉常量表示。通常有多個(gè)操作包含這一相同的結(jié)構(gòu)。State模式將每一個(gè)分支放入一個(gè)獨(dú)立的類中。這使得你可以根據(jù)對象自身的情況將對象的狀態(tài)作為一個(gè)對象,這一對象可以不依賴于其他對象而獨(dú)立變化。
七、 優(yōu)缺點(diǎn)
1) 優(yōu)點(diǎn): 避免了為判斷狀態(tài)而產(chǎn)生的巨大的if或case語句。 將對象行為交給狀態(tài)類維護(hù)后,對于上層程序而言,僅需要維護(hù)狀態(tài)之間的轉(zhuǎn)換規(guī)則。
2) 會(huì)導(dǎo)致某些系統(tǒng)有過多的具體狀態(tài)類。
八、 參考
http://www.cppblog.com/converse/archive/2006/08/07/10902.html
http://www.tkk7.com/flying/archive/2006/08/29/66472.html