狀態模式將對象行為封裝於獨立狀態類中,通過切換狀態對象實現行為動態變化,避免龐大的 if-else 分支。本文以電視機遙控器為例,完整展示接口定義、具體狀態實現、上下文控制類及測試驗證。

if-else/switch 分支。public interface TvState {
void nextChannel();
void prevChannel();
void volumeUp();
void volumeDown();
}
public class PowerOnState implements TvState {
@Override public void nextChannel() { System.out.println("---------下一頻道-----------------------"); }
@Override public void prevChannel() { System.out.println("---------上一頻道-----------------------"); }
@Override public void volumeUp() { System.out.println("---------音量增大-----------------------"); }
@Override public void volumeDown() { System.out.println("---------音量減小-----------------------"); }
}
public class PowerOffState implements TvState {
@Override public void nextChannel() { System.out.println("---------關機狀態不可用,請先開機-----------------------"); }
@Override public void prevChannel() { System.out.println("---------關機狀態不可用,請先開機-----------------------"); }
@Override public void volumeUp() { System.out.println("---------關機狀態不可用,請先開機-----------------------"); }
@Override public void volumeDown() { System.out.println("---------關機狀態不可用,請先開機-----------------------"); }
}
public class TvController {
private TvState tvState;
private boolean isOn = false;
public void setTvState(TvState tvState) { this.tvState = tvState; }
public void turnOn() {
if (!isOn) {
isOn = true;
setTvState(new PowerOnState());
System.out.println("--------開機啦---------------");
} else {
System.out.println("--------已經開機了,不要再按了---------------");
}
}
public void turnOff() {
if (isOn) {
isOn = false;
setTvState(new PowerOffState());
System.out.println("--------關機啦---------------");
} else {
System.out.println("-------已經關機啦,不要再按了---------------");
}
}
// 委派給當前狀態
public void nextChannel() { tvState.nextChannel(); }
public void prevChannel() { tvState.prevChannel(); }
public void volumeUp() { tvState.volumeUp(); }
public void volumeDown() { tvState.volumeDown(); }
}
public class TestClass {
public static void main(String[] args) {
TvController ctrl = new TvController();
ctrl.turnOn(); // 開機
ctrl.turnOn(); // 重複開機提示
ctrl.nextChannel(); // 下一頻道
ctrl.volumeDown(); // 音量減小
ctrl.turnOff(); // 關機
ctrl.turnOff(); // 重複關機提示
ctrl.volumeDown(); // 關機後操作無效
}
}
輸出:
--------開機啦---------------
--------已經開機了,不要再按了---------------
---------下一頻道-----------------------
---------音量減小-----------------------
--------關機啦---------------
-------已經關機啦,不要再按了---------------
---------關機狀態不可用,請先開機-----------------------
setState 明確觸發轉換,便於追蹤與日誌記錄。StateContext 接口,讓狀態類可反向觸發上下文狀態切換(如頻道鎖定自動關機)。