狀態模式允許對象在內部狀態改變時改變其行為,對象看起來像是修改了它的類。本文通過「物體運動/靜止」經典案例,展示如何將狀態相關行為封裝至獨立類中,避免巨大的條件判斷塊,實現開閉原則。
// 環境角色
class Context {
private State state;
public void setState(State state) {
System.out.println("給物體加持狀態");
this.state = state;
}
}
// 抽象狀態
interface State {
void show(Context context);
}
// 具體狀態:運動
class Move implements State {
public void show(Context context) {
context.setState(this);
System.out.println("物體處於運動狀態");
}
}
// 具體狀態:靜止
class Stop implements State {
public void show(Context context) {
context.setState(this);
System.out.println("物體處於靜止狀態");
}
}
// 客戶端調用
public class Demo {
public static void main(String[] args) {
Context context = new Context();
new Move().show(context); // 輸出:給物體加持狀態 / 物體處於運動狀態
new Stop().show(context); // 輸出:給物體加持狀態 / 物體處於靜止狀態
}
}
if-else 或 switch 分支| 優點 | 缺點 |
|---|---|
| 封裝狀態轉換規則,邏輯清晰 | 狀態類過多時增加類數量 |
| 枚舉可能狀態,避免遺漏 | 狀態轉換邏輯分散在各具體狀態類中 |
| 新增狀態無需修改 Context(開閉原則) | 不適用於狀態極少且固定的簡單場景 |
| 可讓多環境對象共享狀態實例(享元) |
canTransitionTo(State target) 方法,集中管理合法轉換路徑狀態模式是處理複雜狀態機的利器,善用它能讓業務邏輯清晰可維護。