P3817 小A的糖果
阿新 • • 發佈:2020-09-08
一、狀態模式介紹
1、定義與型別
允許一個物件在其內部狀態改變時,改變它的行為
型別:行為型
2、適用場景
一個物件存在多個狀態(不同狀態下行為不同),且狀態可相互轉換
3、優點
將不同的狀態隔離
把各種狀態的轉換邏輯,分佈到State的子類中,減少相互間依賴
增加新的狀態非常簡單
4、缺點
狀態多的業務場景導致類數目增加,系統變複雜
5、相關設計模式
狀態模式和享元模式 有時候可以配合進行使用
二、程式碼示例
模擬場景:看視訊時,可以切換為播放狀態、暫停狀態、快進狀態、停止狀態
視訊狀態抽象類:
public abstract class VideoVideoState { // 與上下文 互相巢狀 protected VideoStateContext videoStateContext; public void setVideoStateContext(VideoStateContext videoStateContext) { this.videoStateContext = videoStateContext; } public abstract void paly(); public abstract void speed(); public abstract void pause(); public abstract void stop(); }
播放狀態類:
public class PlayState extends VideoVideoState { @Override public void paly() { System.out.println("正常播放課程視訊的狀態"); } @Override public void speed() { System.out.println("快進了視訊"); super.videoStateContext.setVideoVideoState(VideoStateContext.SPEED_STATE); } @Override public void pause() { System.out.println("暫停了視訊"); super.videoStateContext.setVideoVideoState(VideoStateContext.PAUSE_STATE); } @Override public void stop() { System.out.println("停止了視訊"); super.videoStateContext.setVideoVideoState(VideoStateContext.STOP_STATE); } }
暫停狀態類:
public class PauseState extends VideoVideoState { @Override public void paly() { System.out.println("播放了視訊"); super.videoStateContext.setVideoVideoState(VideoStateContext.PLAY_STATE); } @Override public void speed() { System.out.println("快進了視訊"); super.videoStateContext.setVideoVideoState(VideoStateContext.SPEED_STATE); } @Override public void pause() { System.out.println("暫停播放課程視訊的狀態"); } @Override public void stop() { System.out.println("停止了視訊"); super.videoStateContext.setVideoVideoState(VideoStateContext.STOP_STATE); } }
快進狀態類:
public class SpeedState extends VideoVideoState {
@Override
public void paly() {
System.out.println("播放了視訊");
super.videoStateContext.setVideoVideoState(VideoStateContext.PLAY_STATE);
}
@Override
public void speed() {
System.out.println("快進播放課程視訊的狀態");
}
@Override
public void pause() {
System.out.println("暫停了視訊");
super.videoStateContext.setVideoVideoState(VideoStateContext.PAUSE_STATE);
}
@Override
public void stop() {
System.out.println("停止了視訊");
super.videoStateContext.setVideoVideoState(VideoStateContext.STOP_STATE);
}
}
停止狀態類:
public class StopState extends VideoVideoState {
@Override
public void paly() {
System.out.println("播放了視訊");
super.videoStateContext.setVideoVideoState(VideoStateContext.PLAY_STATE);
}
@Override
public void speed() {
System.out.println("ERROR 停止狀態不能快進!");
}
@Override
public void pause() {
System.out.println("ERROR 停止狀態不能暫停!");
}
@Override
public void stop() {
System.out.println("停止播放課程視訊的狀態");
}
}
視訊狀態上下文(用於管理狀態):
public class VideoStateContext {
// 與視訊狀態類 互相巢狀
private VideoVideoState videoVideoState;
public final static PlayState PLAY_STATE = new PlayState();
public final static SpeedState SPEED_STATE = new SpeedState();
public final static PauseState PAUSE_STATE = new PauseState();
public final static StopState STOP_STATE = new StopState();
public VideoStateContext() {
// 設定預設停止狀態
this.videoVideoState = STOP_STATE;
this.videoVideoState.setVideoStateContext(this);
}
public VideoVideoState getVideoVideoState() {
return videoVideoState;
}
public void setVideoVideoState(VideoVideoState videoVideoState) {
// 切換狀態
this.videoVideoState = videoVideoState;
this.videoVideoState.setVideoStateContext(this);
}
public void paly() {
this.videoVideoState.paly();
}
public void speed() {
this.videoVideoState.speed();
}
public void pause() {
this.videoVideoState.pause();
}
public void stop() {
this.videoVideoState.stop();
}
}
測試類:
public class Test {
public static void main(String[] args) {
VideoStateContext videoStateContext = new VideoStateContext();
videoStateContext.paly();
System.out.println("當前狀態:" + videoStateContext.getVideoVideoState().getClass().getSimpleName());
videoStateContext.pause();
System.out.println("當前狀態:" + videoStateContext.getVideoVideoState().getClass().getSimpleName());
videoStateContext.speed();
System.out.println("當前狀態:" + videoStateContext.getVideoVideoState().getClass().getSimpleName());
videoStateContext.stop();
System.out.println("當前狀態:" + videoStateContext.getVideoVideoState().getClass().getSimpleName());
videoStateContext.speed();
}
}
輸出:
播放了視訊
當前狀態:PlayState
暫停了視訊
當前狀態:PauseState
快進了視訊
當前狀態:SpeedState
停止了視訊
當前狀態:StopState
ERROR 停止狀態不能快進!
類圖: