Java中的有限狀態(tài)機(設計模式——狀態(tài)模式)
Java有限狀態(tài)機 (設計模式——狀態(tài)模式)
編寫代碼的時候,有時會遇見較為復雜的 swith...case...
和 if...else...
語句。
這一刻有時會想到狀態(tài)機,用 有限狀態(tài)機 替換 swith...case...
和 if...else...
可以:
- 降低程序的復雜度;
- 提高程序的可維護性;
- 狀態(tài)機模式體現(xiàn)了開閉原則和單一職責原則。
每個狀態(tài)都是一個子類,增加狀態(tài)就要增加子類;修改狀態(tài)只要修改一個類就行了。
以上是有限狀態(tài)機的好處。
其亦有 缺點:
- 使用狀態(tài)機子類會增多,也就是類膨脹,這點需要程序員在開發(fā)中自己衡量。
狀態(tài)模式定義
Allow an object to alter its behavior when its internal state changes.The object will appear to change its class.
允許對象在其內(nèi)部狀態(tài)發(fā)生變化時更改其行為。
看起來像更改了其類 (這翻譯不好,這里 應該是體現(xiàn)了其封裝性:外部的調用不用知道其內(nèi)部如何實現(xiàn)狀態(tài)和行為變化的)。
舉個例子
我們每天都乘坐電梯,電梯有四種狀態(tài): 開門、關門、運行、停止。
Col1 | 開門 行為 | 關門 行為 | 運行 行為 | 停止 行為 |
---|---|---|---|---|
開門 態(tài) | no | yes | no | no |
關門 態(tài) | yes | no | yes | yes |
運行 態(tài) | no | no | no | yes |
停止 態(tài) | yes | no | yes | no |
LiftState.java
/** * 定義電梯行為:打開、關閉、運行、停止 */ public abstract class LiftState { // 擁有一個電梯對象,用于更新電梯當前狀態(tài) protected Lift mLift; /** * 通過構造函數(shù)引入電梯的實例化對象 * * @param lift */ public LiftState(Lift lift) { this.mLift = lift; } /** * 行為:打開電梯門 */ public abstract void open(); /** * 行為:關閉電梯門 */ public abstract void close(); /** * 行為:電梯運行 */ public abstract void run(); /** * 行為:電梯停止運行 */ public abstract void stop(); }
電梯的四種狀態(tài)
public class OpeningState extends LiftState { public OpeningState(Lift lift) { super(lift); } @Override public void open() { // 執(zhí)行開門動作 System.out.println("執(zhí)行開門動作"); } @Override public void close() { // 執(zhí)行關門動作 // 1、轉化為關門狀態(tài) mLift.setState(mLift.getCloseingState()); // 2、關門 mLift.close(); } @Override public void run() { // do noting // 開門狀態(tài),不能執(zhí)行運行動作 } @Override public void stop() { // do noting // 開門狀態(tài)下,不執(zhí)行停止動作 } }
public class ClosingState extends LiftState { public ClosingState(Lift lift) { super(lift); } @Override public void open() { // 執(zhí)行開門動作 // 1、變化為開門狀態(tài) this.mLift.setState(mLift.getOpenningState()); // 2、開門 this.mLift.open(); } @Override public void close() { System.out.println("執(zhí)行關門動作"); } @Override public void run() { // 運行動作 // 1、運行狀態(tài) this.mLift.setState(mLift.getRunningState()); // 2、運行動作 this.mLift.run(); } @Override public void stop() { // 停止動作 // 1、轉化為停止狀態(tài) this.mLift.setState(mLift.getStoppingState()); // 2、停止 this.mLift.stop(); } }
public class RunningState extends LiftState { public RunningState(Lift lift) { super(lift); } @Override public void open() { // do noting } @Override public void close() { // do noting } @Override public void run() { // 運行動作 System.out.println("電梯上下運行中..."); } @Override public void stop() { // 停止動作 // 1、轉化為停止狀態(tài) this.mLift.setState(mLift.getStoppingState()); // 2、停止動作 this.mLift.stop(); } }
public class StoppingState extends LiftState { public StoppingState(Lift lift) { super(lift); } @Override public void open() { // 開門動作 // 1、開門狀態(tài) this.mLift.setState(mLift.getOpenningState()); // 2、執(zhí)行開門動作 this.mLift.open(); } @Override public void close() { // do noting } @Override public void run() { // 運行動作 // 1、運行狀態(tài) this.mLift.setState(mLift.getRunningState()); // 2、運行動作 this.mLift.run(); } @Override public void stop() { // 電梯停止動作 System.out.println("電梯停止運行..."); } }
定義電梯類
/** * 定義電梯類 */ public class Lift { //定義出電梯的所有狀態(tài) private LiftState openningState; private LiftState closingState; private LiftState runningState; private LiftState stoppingState; // 定義當前電梯狀態(tài) private LiftState mCurState; /** * 構造方法 */ public Lift() { openningState = new OpeningState(this); closingState = new ClosingState(this); runningState = new RunningState(this); stoppingState = new StoppingState(this); } /** * 執(zhí)行開門動作 */ public void open() { mCurState.open(); } /** * 執(zhí)行關門動作 */ public void close() { mCurState.close(); } /** * 執(zhí)行運行動作 */ public void run() { mCurState.run(); } /** * 執(zhí)行停止動作 */ public void stop() { mCurState.stop(); } // ##################設置當前電梯狀態(tài)##################### /** * 設置當前電梯狀態(tài) * * @param state */ public void setState(LiftState state) { this.mCurState = state; } // ###################獲取電梯的全部狀態(tài)#################### public LiftState getOpenningState() { return openningState; } public LiftState getCloseingState() { return closingState; } public LiftState getRunningState() { return runningState; } public LiftState getStoppingState() { return stoppingState; } }
運行
public static void main(String[] args) { Lift lift = new Lift(); lift.setState(new ClosingState(lift)); lift.open(); lift.close(); lift.run(); lift.stop(); }
運行結果
執(zhí)行開門動作
執(zhí)行關門動作
電梯上下運行中...
電梯停止運行...
總結
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
MyBatis游標Cursor在Oracle數(shù)據(jù)庫上的測試方式
這篇文章主要介紹了MyBatis游標Cursor在Oracle數(shù)據(jù)庫上的測試方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01Netty分布式FastThreadLocal的set方法實現(xiàn)邏輯剖析
這篇文章主要為大家介紹了Netty分布式FastThreadLocal的set方法實現(xiàn)邏輯剖析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-03-03深入dom4j使用selectSingleNode方法報錯分析
本篇文章是對dom4j使用selectSingleNode方法報錯進行了詳細的分析介紹,需要的朋友參考下2013-05-05SpringBoot開發(fā)存儲服務器實現(xiàn)過程詳解
這篇文章主要為大家介紹了SpringBoot開發(fā)存儲服務器實現(xiàn)過程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-12-12Java數(shù)據(jù)庫連接池的幾種配置方法(以MySQL數(shù)據(jù)庫為例)
這篇文章主要介紹了Java數(shù)據(jù)庫連接池的幾種配置方法(以MySQL數(shù)據(jù)庫為例) 的相關資料,需要的朋友可以參考下2016-07-07