狀態(tài)模式(State),當(dāng)一個(gè)對象的內(nèi)在狀態(tài)改變時(shí)允許改變其行為,這個(gè)對象看起來像是改變其類。狀態(tài)模式主要解決的是當(dāng)控制一個(gè)對象狀態(tài)轉(zhuǎn)換的條件表達(dá)式過于復(fù)雜時(shí)的情況。把狀態(tài)的判斷邏輯轉(zhuǎn)移到表示不同狀態(tài)的一系列類當(dāng)中,可以把復(fù)雜的判斷邏輯簡化。
狀態(tài)模式的結(jié)構(gòu)圖
狀態(tài)模式中的角色:
- Context:一個(gè) ConcreteState 子類的實(shí)例,這個(gè)實(shí)例定義當(dāng)前的狀態(tài)。
- State:抽象狀態(tài)類,定義一個(gè)接口以封裝與 Context 的一個(gè)特定狀態(tài)相關(guān)的行為。
- ConcreteState:具體狀態(tài)類,每一個(gè)子類實(shí)現(xiàn)一個(gè)與 Context 的一個(gè)狀態(tài)相關(guān)的行為。
狀態(tài)模式的簡單實(shí)現(xiàn)
(1)抽象狀態(tài)類
public abstract class State {
public abstract void handler(Context context);
}
(2)具體狀態(tài)類
public class ConcreteStateA extends State {
@Override
public void handler(Context context) {
context.setState(new ConcreteStateB());
}
}
public class ConcreteStateB extends State {
@Override
public void handler(Context context) {
context.setState(new ConcreteStateA());
}
}
(3)Context 類
public class Context {
private State state;
public Context(State state) {
this.state = state;
}
public void setState(State state) {
System.out.println("當(dāng)前狀態(tài):" + state.getClass().getName());
this.state = state;
}
public State getState() {
return state;
}
public void request() {
state.handler(this);
}
}
(4)客戶端調(diào)用
public class Clinent {
public static void main(String[] args) {
Context context = new Context(new ConcreteStateA());
context.request();
context.request();
context.request();
context.request();
}
}
(5)輸出
當(dāng)前狀態(tài):...State.ConcreteStateB
當(dāng)前狀態(tài):...State.ConcreteStateA
當(dāng)前狀態(tài):...State.ConcreteStateB
當(dāng)前狀態(tài):...State.ConcreteStateA
狀態(tài)模式的使用場景
使用場景:
一個(gè)對象的行為取決于它的狀態(tài),并且它必須在運(yùn)行時(shí)刻根據(jù)狀態(tài)改變它的行為。
一個(gè)操作中含有龐大的多分支結(jié)構(gòu),并且這些分支決定于對象的狀態(tài)。