狀態(tài)( State )模式:允許一個(gè)對象在其內(nèi)部狀態(tài)改變時(shí)改變它的行為。對象看起來似乎修改了它的類。

適用性:

  • 一個(gè)對象的行為取決于它的狀態(tài), 并且它必須在運(yùn)行時(shí)刻根據(jù)狀態(tài)改變它的行為。
  • 一個(gè)操作中含有龐大的多分支的條件語句,且這些分支依賴于該對象的狀態(tài)。這個(gè)狀態(tài)通常用一個(gè)或多個(gè)枚舉常量表示。通常, 有多個(gè)操作包含這一相同的條件結(jié)構(gòu)。State模式將每一個(gè)條件分支放入一個(gè)獨(dú)立的類中。這使得你可以根據(jù)對象自身的情況將對象的狀態(tài)作為一個(gè)對象,這一對象可以不依賴于其他對象而獨(dú)立變化。

所涉及的角色:

抽象狀態(tài) (State) 角色:定義一個(gè)接口,用以封裝對象的一個(gè)特定狀態(tài)所對應(yīng)的形為。

具體狀態(tài) (Concrete State) 角色:每一個(gè)具體狀態(tài)類都實(shí)現(xiàn)環(huán)境( Context )的一個(gè)狀態(tài)所對應(yīng)的行為。

環(huán)境( Context )角色:定義客戶端所感興趣的接口,并且保留一個(gè)具體狀態(tài)類的實(shí)例。這個(gè)具體狀態(tài)類的實(shí)例給出些環(huán)境對象的現(xiàn)有狀態(tài)。
state.bmp
一個(gè)簡單的例子:

抽象狀態(tài)State類

package ?State;

public ? interface ?State {
????
// 接口方法
???? void ?operator();
}


具體狀態(tài)類ConcreteStateA和ConcreteStateB:

package ?State;

public ? class ?ConcreteStateA? implements ?State {
????
// 實(shí)現(xiàn)接口方法
???? public ? void ?operator() {
????????System.out.println(
" The?ConcreteStateA " );
????}

}
package ?State;

public ? class ?ConcreteStateB? implements ?State {
????
// 實(shí)現(xiàn)接口方法
???? public ? void ?operator() {
????????System.out.println(
" The?ConcreteStateB " );
????}

}

環(huán)境Context類
package?State;

public?class?Context{
????
private?State?state;
????
//狀態(tài)賦值方法
????public?void?setState(State?state){
????????
this.state=state;
????}

????
//委派方法
????public?void?operator(){
????????state.operator();
????}

}
客戶端類:
package?State;

public?class?Client{
????
private?static?State?state=null;
????
private?static?Context?context=null;
????
????
public?static?void?main(String[]?args){
????????
????????context
=new?Context();
????????state
=new?ConcreteStateA();
????????context.setState(state);
????????context.operator();
????????state
=new?ConcreteStateB();
????????context.setState(state);
????????context.operator();
????}

}

狀態(tài)模式與策略模式的區(qū)別:

兩個(gè)模式很容易混淆,區(qū)別兩者的一個(gè)方法是考察環(huán)境角色是否有明顯的狀態(tài)和狀態(tài)過渡。如果環(huán)境角色只有一個(gè)狀態(tài),那么就應(yīng)當(dāng)使用策略模式。策略模式的特點(diǎn):一旦環(huán)境角色選擇了一個(gè)具體的策略類,那么在整個(gè)環(huán)境類的生命周期里它都不會改變這個(gè)具體策略類。而狀態(tài)模式則適用另一情況,即環(huán)境角色有明顯的狀態(tài)轉(zhuǎn)移。在環(huán)境類的生命周期里面,會有幾個(gè)不同的狀態(tài)被使用。

另外一個(gè)微妙的區(qū)別在于策略模式的環(huán)境自己選擇一個(gè)具體的策略類,而狀態(tài)模式的環(huán)境類是被外在原因放進(jìn)一個(gè)具體的狀態(tài)中。

策略模式所選擇的策略類往往不明顯的告訴客戶端它所選擇的具體策略類,而狀態(tài)模式則相反,環(huán)境角色所處的狀態(tài)是明顯告訴客戶端的。

參考資料:《java與模式》
《設(shè)計(jì)模式速查手冊》
http://blog.csdn.net/qutr/archive/2006/08/01/1007617.aspx