定義
允許一個對象在其內部狀態改變時,改變它的行爲。
類型
行爲型
適用場景
①、一個對象存在多個狀態(不同狀態下行爲不同),且狀態可相互轉換。
優缺點
優點:
①、將不同的狀態隔離。
②、把各種狀態的轉換邏輯,分佈到State的子類中,減少相互間依賴。
③、增加新的狀態非常簡單。
缺點:
①、狀態多的業務場景導致類數目增加,系統變複雜。
代碼實現
案例:博主經常在B站看番,有時候會快進、有時候會暫停、看完了就關閉當前視屏了。可以看到,視屏是有很多狀態的:開始播放、暫停播放、快進播放、停止播放。
首先創建一個視頻的狀態類
public abstract class CourseVideoState {
protected CourseVideoContext courseVideoContext;
public void setCourseVideoContext(CourseVideoContext courseVideoContext) {
this.courseVideoContext = courseVideoContext;
}
public abstract void play();
public abstract void speed();
public abstract void pause();
public abstract void stop();
}
CourseVideoContext這個類是視頻的上下文。裏面是做視頻狀態的切換以及狀態的管理。
public class CourseVideoContext {
private CourseVideoState courseVideoState;
public final static PlayState PLAY_STATE = new PlayState();
public final static StopState STOP_STATE = new StopState();
public final static PauseState PAUSE_STATE = new PauseState();
public final static SpeedState SPEED_STATE = new SpeedState();
public CourseVideoState getCourseVideoState() {
return courseVideoState;
}
public void setCourseVideoState(CourseVideoState courseVideoState) {
this.courseVideoState = courseVideoState;
this.courseVideoState.setCourseVideoContext(this);
}
public void play() {
this.courseVideoState.play();
}
public void speed() {
this.courseVideoState.speed();
}
public void pause() {
this.courseVideoState.pause();
}
public void stop() {
this.courseVideoState.stop();
}
}
this.courseVideoState.setCourseVideoContext(this)這個方法,用來刷新最新的上下文。
上面還聲明瞭四種狀態的常量,接下來一一創建。
創建開始播放狀態CourseVideoState的實現類。
public class PlayState extends CourseVideoState {
@Override
public void play() {
System.out.println("狀態:播放視頻");
}
@Override
public void speed() {
super.courseVideoContext.setCourseVideoState(CourseVideoContext.SPEED_STATE);
}
@Override
public void pause() {
super.courseVideoContext.setCourseVideoState(CourseVideoContext.PAUSE_STATE);
}
@Override
public void stop() {
super.courseVideoContext.setCourseVideoState(CourseVideoContext.STOP_STATE);
}
}
視頻開始播放,都能隨時切換到其他的三種狀態。
創建暫停播放狀態CourseVideoState的實現類。
public class PauseState extends CourseVideoState {
@Override
public void play() {
super.courseVideoContext.setCourseVideoState(CourseVideoContext.PLAY_STATE);
}
@Override
public void speed() {
super.courseVideoContext.setCourseVideoState(CourseVideoContext.SPEED_STATE);
}
@Override
public void pause() {
System.out.println("狀態:暫停視頻");
}
@Override
public void stop() {
super.courseVideoContext.setCourseVideoState(CourseVideoContext.STOP_STATE);
}
}
暫停視屏的時候,也是能夠切換到其他三種狀態的。
創建快進播放狀態CourseVideoState的實現類。
public class SpeedState extends CourseVideoState {
@Override
public void play() {
super.courseVideoContext.setCourseVideoState(CourseVideoContext.PLAY_STATE);
}
@Override
public void speed() {
System.out.println("狀態:快進視頻");
}
@Override
public void pause() {
super.courseVideoContext.setCourseVideoState(CourseVideoContext.PAUSE_STATE);
}
@Override
public void stop() {
super.courseVideoContext.setCourseVideoState(CourseVideoContext.STOP_STATE);
}
}
快進和暫停相似。
創建停止播放狀態CourseVideoState的實現類。
public class StopState extends CourseVideoState {
@Override
public void play() {
super.courseVideoContext.setCourseVideoState(CourseVideoContext.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 static void main(String[] args) {
CourseVideoContext courseVideoContext = new CourseVideoContext();
// 初始化狀態爲播放狀態
courseVideoContext.setCourseVideoState(new PlayState());
System.out.println("當前狀態:" + courseVideoContext.getCourseVideoState().getClass().getSimpleName());
// 暫停
courseVideoContext.pause();
System.out.println("當前狀態:" + courseVideoContext.getCourseVideoState().getClass().getSimpleName());
// 快進
courseVideoContext.speed();
System.out.println("當前狀態:" + courseVideoContext.getCourseVideoState().getClass().getSimpleName());
// 停止播放
courseVideoContext.stop();
System.out.println("當前狀態:" + courseVideoContext.getCourseVideoState().getClass().getSimpleName());
// 停止播放的狀態下切換SpeedState或者PauseState狀態,會報錯
courseVideoContext.pause();
System.out.println("當前狀態:" + courseVideoContext.getCourseVideoState().getClass().getSimpleName());
}
}
輸出結果:
相關源碼
1. JSF中的Lifecycle類