設計模式之狀態模式---State Pattern
模式的定義
狀態模式定義如下:
Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.
當一個物件內在狀態改變時允許其改變行為,這個物件看起來像改變了其類
模式的使用場景
- 行為隨狀態改變而改變的場景
這就是狀態模式的根本出發點,例如許可權設計,人員的狀態不同即使執行相同的行為結果也會不同,在這種情況下需要考慮使用狀態模式
- 條件,分支判斷語句的替代者
在程式中大量使用switch語句或者if判斷語句會導致程式結構不清晰,邏輯混亂,使用狀態模式可以很好的避免這一問題,它通過擴充套件子類來實現對條件的判斷處理。
UML類圖
角色介紹
- State—-抽象狀態角色
介面或抽象類,負責物件狀態定義,並且封裝環境角色以實現狀態切換。
- ConcreteState—-具體狀態角色
每一個具體狀態必須完成二個職責:本狀態的行為以及趨向狀態處理,也就是本狀態下要做的事,以及本狀態如何過渡到其它狀態。
Context—-環境角色
定義客戶端需要的介面,並且負責具體的狀態切換。
狀態模式相對來說比較複雜,它提供了一種對物質運動的另一個觀察視角,通過對狀態變更促進行為的變化,就類似水的狀態變更一樣,一碗水的初始狀態是液態,通過加熱轉變為氣態,狀態的變化同時也引起了體積的擴大,然後就產生了新的行為。
模式的通用原始碼
State—抽象狀態角色
抽象State中宣告一個環境角色,提供各個狀態類自行訪問,並且提供所有狀態的抽象行為,由各個實現類實現。
public abstract class State {
//定義一個環境角色,提供子類訪問
protected Context context;
//設定環境角色
public void setContext(Context context){
this.context = context;
}
//行為1
public abstract void handle1();
//行為2
public abstract void handle2();
}
ConcreteState1 —具體狀態1,handle1處理本狀態的行為,handle2處理狀態過渡
public class ConcreteState1 extends State{
@Override
public void handle1() {
// TODO Auto-generated method stub
System.out.println("ConcreteState1---handle1");
}
@Override
public void handle2() {
// TODO Auto-generated method stub
System.out.println("ConcreteState1---handle2");
super.context.setCurrentState(Context.STATE2);
super.context.handle2();
}
}
ConcreteState2 —具體狀態2,handle2處理本狀態的行為,handle1處理狀態過渡
public class ConcreteState2 extends State{
@Override
public void handle1() {
// TODO Auto-generated method stub
System.out.println("ConcreteState2---handle1");
super.context.setCurrentState(Context.STATE1);
super.context.handle1();
}
@Override
public void handle2() {
// TODO Auto-generated method stub
System.out.println("ConcreteState2---handle2");
}
}
具體狀態有二個職責,處理本狀態必須完成的行為,決定是否可以過濾到其它狀態。
Context —-環境角色
public class Context {
//定義狀態
public final static State STATE1 = new ConcreteState1();
public final static State STATE2 = new ConcreteState2();
//當前狀態
private State currentState;
//獲得當前狀態
public State getState(){
return this.currentState;
}
//設定當前狀態
public void setCurrentState(State state){
this.currentState = state;
//切換狀態
this.currentState.setContext(this);
}
//行為委託
public void handle1(){
this.currentState.handle1();
}
//行為委託
public void handle2(){
this.currentState.handle2();
}
}
環境角色有二個不成文的約束:
- 把狀態物件宣告為靜態常量,有幾個狀態物件就宣告幾個靜態常量
- 環境角色具有狀態抽象角色定義的所有行為,具體執行使用委託的方式
Client —客戶呼叫端:
public class Client {
public static void main(String[] args) {
// TODO Auto-generated method stub
Context context = new Context();
context.setCurrentState(new ConcreteState1());
System.out.println("Client---context.handle1()");
context.handle1();
System.out.println("Client---context.handle2()");
context.handle2();
}
}
程式輸出:
Client---context.handle1()
ConcreteState1---handle1
Client---context.handle2()
ConcreteState1---handle2
ConcreteState2---handle2
優點
- 結構清晰
避免了過多的switch case 或者 if else語句的使用,避免了程式的複雜性,提高系統的可維護性
- 遵循設計原則
很好的體現了開閉原則和單一職責原則,每個狀態都是一個子類,你要增加狀態就要增加子類,你要修改狀態,你只修改一個子類就可以了。
- 封裝性好
狀態變換放置到類的內部來實現,外部的呼叫不用知道類內部如何實現狀態和行為的變換。
缺點
子類太多,就是類膨脹。如果一個事物有很多個狀態,那麼我們使用狀態模式就會有太多的子類,不好管理。這個問題需要大家在專案中自己衡量。當然,解決此問題也有許多方法,比如在資料庫中建立一個狀態表,然後根據狀態執行相應的操作。
注意事項
狀態模式適用於當物件在它的狀態發生改變時,它的行為也隨著發生比較大的改變,也就是說行為受狀態約束的情況下可以使用狀態模式,而且使用時物件的狀態最好不要超過5個。
Android原始碼中的模式實現
UML類圖
具體實現程式碼
參考資料
(1).設計模式之禪—第26章 狀態模式
(2)狀態模式
https://github.com/simple-android-framework/android_design_patterns_analysis/tree/master/state
相關文章
- JAVA設計模式之 狀態模式【State Pattern】Java設計模式
- 設計模式-狀態模式(State Pattern)設計模式
- 設計模式之策略模式和狀態模式(strategy pattern & state pattern)設計模式
- 狀態模式(State pattern)模式
- 設計模式之狀態模式(State)設計模式
- 設計模式——20狀態模式(State)設計模式
- 使用C# (.NET Core) 實現狀態設計模式 (State Pattern)C#設計模式
- C#設計模式系列:狀態模式(State)C#設計模式
- 設計模式--狀態模式State(行為型)設計模式
- 23種設計模式 之 State模式(狀態模式)[C語言實現]設計模式C語言
- 狀態模式(State)模式
- 設計模式之——狀態模式設計模式
- 【設計模式基礎】行為模式 - 8 -狀態(State)設計模式
- PHP 設計模式之狀態模式PHP設計模式
- 設計模式20之狀態模式設計模式
- Java設計模式之狀態模式Java設計模式
- 設計模式系列之「狀態模式」設計模式
- 設計模式之State設計模式
- 設計模式漫談之狀態模式設計模式
- C#設計模式之狀態模式C#設計模式
- 設計模式系列之十二狀態模式設計模式
- 我學設計模式 之 狀態模式設計模式
- 轉載---Dephi狀態模式(State模式)模式
- 設計模式之代理模式(proxy pattern)設計模式
- 設計模式-狀態模式設計模式
- 設計模式:狀態模式設計模式
- 折騰Java設計模式之狀態模式Java設計模式
- Unity【話大】設計模式之狀態模式Unity設計模式
- 設計模式之觀察者模式(Observer Pattern)設計模式Server
- JAVA設計模式之 代理模式【Proxy Pattern】Java設計模式
- 設計模式(十五)狀態模式設計模式
- javascript設計模式狀態模式JavaScript設計模式
- 設計模式(六):狀態模式設計模式
- 設計模式學習筆記之狀態模式設計模式筆記
- 1/24 設計模式之策略設計模式 Strategy Pattern設計模式
- 設計模式之——Singleton pattern設計模式
- 設計模式之裝飾器模式(decorator pattern)設計模式
- 設計模式之單例模式(Singleton Pattern)設計模式單例