設(shè)計(jì)模式學(xué)習(xí)筆記(十五)—State模式
Posted on 2007-12-05 16:35 flustar 閱讀(1603) 評(píng)論(1) 編輯 收藏 所屬分類(lèi): Design Patterns一、 State模式定義:
允許一個(gè)對(duì)象在其狀態(tài)改變時(shí),改變它的行為。看起來(lái)對(duì)象似乎修改了它的類(lèi)。
二、 模式解說(shuō)
State模式主要解決的是在開(kāi)發(fā)中時(shí)常遇到的根據(jù)不同的狀態(tài)需要進(jìn)行不同的處理操作的問(wèn)題,而這樣的問(wèn)題,大部分人是采用switch-case語(yǔ)句進(jìn)行處理的,這樣會(huì)造成一個(gè)問(wèn)題:分支過(guò)多,而且如果加入一個(gè)新的狀態(tài)就需要對(duì)原來(lái)的代碼進(jìn)行編譯。State模式采用了對(duì)這些不同的狀態(tài)進(jìn)行封裝的方式處理這類(lèi)問(wèn)題,當(dāng)狀態(tài)改變的時(shí)候進(jìn)行處理然后再切換到另一種狀態(tài),也就是說(shuō)把狀態(tài)的切換責(zé)任交給了具體的狀態(tài)類(lèi)去負(fù)責(zé).同時(shí),State模式和Strategy模式有很多相似的地方,需要說(shuō)明的是兩者的思想都是一致的,只不過(guò)封裝的東西不同:State模式封裝的是不同的狀態(tài),而Stategy模式封裝的是不同的算法。
三、 結(jié)構(gòu)圖
State模式結(jié)構(gòu)圖如下:
四、 怎么使用?
1) 定義一個(gè)State接口,接口中有一個(gè)統(tǒng)一的方法,用以封裝一個(gè)特定狀態(tài)所對(duì)應(yīng)的行為。
2) 定義具體不同狀態(tài)類(lèi)ConcreteSate實(shí)現(xiàn)State接口。
3) 每一個(gè)狀態(tài)類(lèi)都實(shí)現(xiàn)環(huán)境(Context)一個(gè)狀態(tài)所對(duì)應(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
每請(qǐng)求一次,狀態(tài)就更換一次,就執(zhí)行對(duì)應(yīng)的行為。
六、 適用性
1) 一個(gè)對(duì)象的行為取決于它的狀態(tài),并且它必須在運(yùn)行時(shí)刻根據(jù)狀態(tài)改變它的行為。
2) 一個(gè)對(duì)象含有龐大的條件分支語(yǔ)句,這些分支依賴(lài)于它的狀態(tài)。這個(gè)狀態(tài)通常用一個(gè)或多個(gè)枚舉常量表示。通常有多個(gè)操作包含這一相同的結(jié)構(gòu)。State模式將每一個(gè)分支放入一個(gè)獨(dú)立的類(lèi)中。這使得你可以根據(jù)對(duì)象自身的情況將對(duì)象的狀態(tài)作為一個(gè)對(duì)象,這一對(duì)象可以不依賴(lài)于其他對(duì)象而獨(dú)立變化。
七、 優(yōu)缺點(diǎn)
1) 優(yōu)點(diǎn): 避免了為判斷狀態(tài)而產(chǎn)生的巨大的if或case語(yǔ)句。 將對(duì)象行為交給狀態(tài)類(lèi)維護(hù)后,對(duì)于上層程序而言,僅需要維護(hù)狀態(tài)之間的轉(zhuǎn)換規(guī)則。
2) 會(huì)導(dǎo)致某些系統(tǒng)有過(guò)多的具體狀態(tài)類(lèi)。
八、 參考
http://www.cppblog.com/converse/archive/2006/08/07/10902.html
http://www.aygfsteel.com/flying/archive/2006/08/29/66472.html