設計模式(十五)狀態模式

請直接看原文:
設計模式系列

-------------------------------------------------------------------------------------------------------------------------------?

前言

建議在閱讀本文前先閱讀設計模式(十一)策略模式這篇文章,雖說狀態模式和策略模式的結構幾乎是相同的,但是它們所解決的問題是不同的,讀完這兩篇文章你就會有了答案。

1.狀態模式定義
狀態模式定義

定義:當一個對象的內在狀態改變時允許改變其行為,這個對象看起來像是改變了其類。

狀態模式UML圖

在享元模式中有如下角色:

  • Context:環境角色,定義客戶端需要的接口,并且負責具體狀態的切換。
  • State:抽象狀態角色,可以是抽象類或者接口,負責對象狀態定義,并封裝了環境角色。
  • ConcreteState:具體狀態角色,實現抽象角色類,定義了本狀態所要做的事情。
2.簡單實現狀態模式

拿用mp3聽歌來說,mp3有四種基本狀態,分別是開機、關機、上一首歌和下一首歌。如果我們要寫一個對mp3進行控制的類,你可能會這樣寫,如下所示。

public class Mp3Controller {private static final int POWER_ON = 1;private static final int POWER_OFF = 2;private int state = POWER_OFF;public void powerOn() {if (state == POWER_OFF) {System.out.println("開機");}state = POWER_ON;}public void powerOff() {if (state == POWER_ON) {System.out.println("關機");}state = POWER_OFF;}public void preSong() {if (state == POWER_ON) {System.out.println("上一首歌");}}public void nextSong() {if (state == POWER_ON) {System.out.println("下一首歌");}}
}

在powerOn和powerOff方法中我們會將state置為相應的狀態,在preSong和nextSong方法中,首先要判斷當前mp3的state,如果是POWER_OFF,則不做任何處理,寫到這里你可能會覺得實現很簡單啊。那么我再添加些狀態,比如待機狀態、休眠狀態、亮屏狀態等等,順便再添加些功能,比如調大音量、調小音量、降噪等。這樣你實現起來,就會發現你會定義很多種狀態,在功能中可能要用到多個條件語句進行判斷,這會使得代碼變得臃腫。
狀態模式就是為了解決這一問題,將多個條件語句去掉,使得代碼更加清晰,下面來進行實現。

抽象狀態角色
public interface Mp3State {//開機public void powerOn();//關機public void powerOff();//上一首歌曲public void preSong();//下一首歌曲public void nextSong();
}

接口Mp3State中定義了四種功能,接下來我們來實現Mp3State。

具體狀態角色

我們先來實現開機狀態,代碼如下所示。

public class PowerOnState implements Mp3State {@Overridepublic void powerOn() {System.out.println("已開機");}@Overridepublic void powerOff() {System.out.println("關機");}@Overridepublic void preSong() {System.out.println("上一首歌");}@Overridepublic void nextSong() {System.out.println("下一首歌");}
}

比較特殊的是powerOn方法中,打印了“已開機”,因為在PowerOnState 狀態下進行開機操作是多此一舉的。
接著實現關機狀態:

public class PowerOffState implements Mp3State {@Overridepublic void powerOn() {System.out.println("開機");}@Overridepublic void powerOff() {}@Overridepublic void preSong() {}@Overridepublic void nextSong() {}
}

在關機狀態中只實現了powerOn方法,其他的方法都是空實現。

環境角色
public class Context {private Mp3State mp3State;public void setMp3State(Mp3State mp3State){this.mp3State=mp3State;}public void powerOn(){mp3State.powerOn();setMp3State(new PowerOnState());}public void powerOff(){mp3State.powerOff();setMp3State(new PowerOffState());}public void preSong(){mp3State.preSong();}public void nextSong(){mp3State.nextSong();}
}

Context 中定義了setMp3State方法,用來設定狀態,其中powerOn方法中會調用setMp3State方法將狀態置為PowerOffState,同理powerOff中將狀態置為PowerOffState。

客戶端調用
public class Client {public static void main(String[] args){Context context=new Context();context.setMp3State(new PowerOffState());context.preSong();context.powerOn();context.nextSong();context.powerOff();}
}

我們只需要先設定mp3的初始狀態,就可以調用各種功能方法了,不需要再考慮功能和狀態之間的關系。輸出結果為:
開機
下一首歌
關機

雖然這個例子的代碼很簡單,這里還是給出UML圖,如下所示。

3.狀態模式的使用場景和優缺點
優點
  • 避免了過多的條件語句,使得結構更清晰,提高代碼的可維護性。
  • 每個狀態都是一個子類,方便增加和修改狀態。
  • 狀態被放置到類的內部,外部調用不需要知道類的內部如何實現狀態和行為的變換。
缺點
  • 完全使用狀態模式,可能會導致子類會過多。
使用場景
  • 代碼中包含大量與對象狀態有關的條件語句。
  • 對象的行為依賴著狀態,并且行為隨著狀態的改變而改變。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/717792.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/717792.shtml
英文地址,請注明出處:http://en.pswp.cn/news/717792.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

java.sqlrecoverableexception: io error: the network adapter could not establ

數據庫相關學習資料下載地址: 數據庫相關資料合集 Java SQLRecoverableException: IO Error: The Network Adapter Could Not Establish Connection 在進行Java開發中,經常會遇到與數據庫進行交互的情況。然而,有時候我們可能會遇到java.sq…

Redis過期刪除策略

1、定時刪除: 一旦鍵過期就立即從內存中刪除,節省內存空間,但刪除過程會占用大量CPU時間,可能影響服務器的響應時間和吞吐量。 2、惰性刪除: 并不會立即從內存中刪除過期鍵,而是在需要訪問時才會檢查是否…

【MATLAB】MVMD_ MFE_SVM_LSTM 神經網絡時序預測算法

有意向獲取代碼,請轉文末觀看代碼獲取方式~也可轉原文鏈接獲取~ 1 基本定義 MVMD_MFE_SVM_LSTM神經網絡時序預測算法結合了多變量多尺度分解(MVMD)、多尺度特征提取(MFE)、支持向量機(SVM)和長…

Python爬蟲之爬取并下載嗶哩嗶哩視頻

親自使用過,太好用了 # 導入requests模塊,模擬發送請求 import requests # 導入json import json # 導入re import re# 定義請求頭 headers {Accept: */*,Accept-Language: en-US,en;q0.5,User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6…

小米消息隊列的選型與實踐

之前寫了一篇關于消息隊列的文章:《消息隊列介紹與對比》,本文主要介紹消息隊列在實際工作中的使用情況(截止到2023年,因為我2023年離職了,后續的情況不了解了,哈哈)。 市面上的多種消息隊列都有…

node問題: command not found: nodemon

如何安裝并使用 nodemon npm i -g nodemon 問題與解決方案: 問題:zsh: command not found: nodemon 解決方案: 在你的 package.json 中加入: "scripts": {"auto": "npx nodemon server.js" }…

單例模式及應用場景

如果希望自己的代碼更優雅、可維護性更高以及更簡潔,往往離不開設計模式這一解決方案。 在JS設計模式中,最核心的思想:封裝變化(將變與不變分離,確保變化的部分靈活,不變的部分穩定)。 那么來…

[嵌入式系統-36]:龍芯1B 開發學習套件 -5- PMON常見命令

目錄 0. 開機時按c鍵進入pmon模式 (自啟動模式時) 1、幫助命令 h 2、顯示設備信息 devls 3.重啟:reboot 4、設置環境變量 set/unset 5.查詢環境變量:env 6.網絡設置相關命令: ①設置IP:ifconfig&am…

Linux 基礎IO(1)內存文件

文章目錄 鋪墊文件的系統調用接口文件描述符緩沖區 鋪墊 文件文件內容 文件屬性訪問文件之前,都要先打開文件,而要訪問,修改,編輯文件,文件就必須加載到內存中程序運行起來變成進程,被CPU調度,…

詳解Win 7重置電腦操作步驟

文章目錄 介紹Win 7 重置系統的方法:1.按下鍵盤上的Windows鍵和R鍵,打開運行窗口,輸入sysprep 點擊回車確定。2.之后就會出現如下界面,在這個新打開的窗口中雙擊 sysprep 程序3.選擇【進入系統全新體驗(00BE) 】&#…

基于SpringBoot的在線拍賣系統(附項目源碼+論文)

摘要 在線拍賣系統,主要的模塊包括管理員;首頁、個人中心、用戶管理、商品類型管理、拍賣商品管理、歷史競拍管理、競拍訂單管理、留言板管理、系統管理,用戶;首頁、個人中心、歷史競拍管理、競拍訂單管理、留言板管理&#xff0…

Linux重新獲取IP地址

你可以通過重啟客戶端來獲取新的IP地址。可以使用以下命令來重啟DHCP客戶端: sudo dhclient -r # 釋放當前IP sudo dhclient # 獲取新的IP 這將釋放當前的IP地址,并請求新的IP地址。 使用ifdown和ifup命令:另一種方法是使用ifdown和i…

STM32學習和實踐筆記(1): 裝好了的keil μVision 5

2019年3月在淘寶上買了這塊STM32的開發板,學了一段時間后就丟下了,今天重新撿起來,決定好好學習、天天向上。 對照教程,今天先把keil5裝上了。 裝的過程有以下幾點值得記錄下: 1)用注冊機時,…

【應用多元統計分析】--多元數據的直觀表示(R語言作圖)

例1.2 為了研究全國31個省、市、自治區2018年城鎮居民生活消費的分布規律,根據調查資料做區域消費類型劃分。 指標: 食品x1:人均食品支出(元/人) 衣著x2:人均衣著商品支出(元/人) 居住x3:人均居住支出(元/人) 生活x4…

歐拉回路(Eulerian Path)

1.定義 如果圖 G G G(有向圖或者無向圖)中所有邊一次僅且一次行遍所有頂點的通路稱作歐拉通路。 如果圖 G G G中所有邊一次僅且一次行遍所有頂點的回路稱作歐拉回路。 具有歐拉回路的圖成為歐拉圖(簡稱 E E E圖)。具有歐拉通路但不具有歐拉回路的圖成為半歐拉圖。 頂點可以經…

【Linux】Linux常用指令介紹

目錄 1、whoami命令 2、pwd命令 3、ls命令 4、cd命令 5、touch命令 6、mkdir命令 7、rm命令 8、man命令 9、cp命令 10、mv命令 11、cat命令 12、more命令 13、less命令 14、head命令 15、tail命令 16、find命令 1、whoami命令 語法:whoani 功能&a…

SpringMVC--03--前端傳數組給后臺

提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔 文章目錄 案例1乘客個人信息方法1:表單提交,以字段數組接收方法2:表單提交,以BeanListModel接收方法3:將Json對象序…

leetcode移除元素

注意,在本題中,是對原數組進行操作,需要原地刪除指定元素,所以我們可以采用快慢指針來操作。 顧名思義,快慢指針是有兩個指針,一直快指針,一個慢指針。在本題中,快慢指針起點都是0&a…

解鎖人體姿態的秘密:部件親和場(PAF)的革新應用

部件親和場(PAF)原理及其在人體姿態估計中的應用 摘要: 隨著人工智能技術的發展,人體姿態估計在計算機視覺領域受到越來越多的關注。部件親和場(Part Affinity Fields,簡稱PAF)作為一種新興的人體姿態估計技術,通過構建2D向量場來描述人體肢體的方向和位置信息,從而…

Matlab 機器人工具箱 運動學

文章目錄 R.fkine()R.ikine()R.ikine6s()R.ikuncR.jacob0、R.jacobn、R.jacob_dotjtrajctraj參考鏈接 官網:Robotics Toolbox - Peter Corke R.fkine() 正運動學,根據關節坐標求末端執行器位姿 mdl_puma560; % 加載puma560模型 qz % 零角度 qr …