【設計模式】行為型-狀態模式

在變幻的時光中,狀態如詩篇般細膩流轉。

文章目錄

  • 一、可調節的燈光
  • 二、狀態模式
  • 三、狀態模式的核心組件
  • 四、運用狀態模式
  • 五、狀態模式的應用場景
  • 六、小結
  • 推薦閱讀

一、可調節的燈光

場景假設:我們有一個電燈,它可以被打開和關閉。用戶可以通過一個開關來改變電燈的狀態。

/*** 表示可以開關的燈的類。*/
public class Light {private String state; // 燈的當前狀態,可能是"ON"或者"OFF"/*** 構造方法,初始化燈的狀態為"OFF"。*/public Light() {this.state = "OFF";}/*** 開關燈的狀態。* 如果燈當前為"OFF",則將其改為"ON"并打印"燈已打開"。* 如果燈當前為"ON",則將其改為"OFF"并打印"燈已關閉"。*/public void switchState() {if ("OFF".equals(state)) {state = "ON";System.out.println("燈已打開");} else {state = "OFF";System.out.println("燈已關閉");}}
}

上面的代碼雖然能夠實現需求,因為只有兩種狀態。但是,如果電燈有更多的狀態,比如“調暗”、“調亮”、“閃爍”等,那么 switchState 方法就會變得非常復雜,充滿了 if-else 語句。這將使代碼難以閱讀和維護。

二、狀態模式

狀態模式(State Pattern)是一種行為型設計模式,它允許對象在其內部狀態發生改變時改變其行為,使其看起來像是改變了其類。狀態模式的關鍵思想是將對象的行為封裝在不同的狀態對象中,并且在狀態轉換時可以動態地改變對象的行為。

三、狀態模式的核心組件

狀態模式的核心組件包括以下幾個角色:

  1. Context(上下文):上下文是擁有狀態的對象。它定義了客戶端感興趣的接口,并且維護一個當前狀態對象,這個狀態對象定義了當前的狀態和相應的行為。Context 可以通過狀態對象來改變它的行為。
  2. State(狀態):狀態是一個接口或者抽象類,它封裝了與 Context 的一個特定狀態相關的行為。在 State 接口或者抽象類中定義了所有具體狀態類所共享的方法,這些方法的實現將依賴于當前狀態。通常,這些方法處理與狀態相關的操作,如請求或者事件。
  3. ConcreteState(具體狀態):具體狀態類實現了 State 接口或者繼承了 State 抽象類。每個具體狀態類實現了與 Context 的一個狀態相關的行為。例如,在電梯系統中,可能會有開門狀態、關門狀態、運行狀態和停止狀態等具體狀態類。

在這里插入圖片描述

這個類圖展示了狀態模式的核心組成部分:

  • State 接口定義了 doAction(Context) 方法,表示所有具體狀態類(OpenState 和 CloseState)需要實現的方法。
  • OpenState 和 CloseState 類分別實現了 State 接口,并實現了 doAction(Context) 方法來處理具體的狀態操作。
  • Context 類包含一個狀態接口類型的私有成員變量 state,通過 setState(State) 方法設置當前的狀態,并通過 request() 方法執行當前狀態的動作。

四、運用狀態模式

場景假設:我們有一個電燈,它可以被打開和關閉。用戶可以通過一個開關來改變電燈的狀態。電燈有更多的狀態,比如“調暗”、“調亮”、“閃爍”等。

  1. 定義狀態接口:首先,我們需要定義一個狀態接口,該接口聲明了所有具體狀態類需要實現的方法。在我們的例子中,我們可以定義一個 LightState 接口,該接口有一個 switchState 方法。

    // 定義狀態接口
    public interface LightState {// 聲明改變狀態的方法,接收一個 Light 對象作為參數void switchState(Light light);
    }
    
  2. 創建具體狀態類:然后,我們需要為每種狀態創建一個具體的狀態類。這些類需要實現狀態接口,并實現接口中聲明的方法。在我們的例子中,我們可以創建 OnState 和 OffState 類。

    // 創建具體狀態類:打開狀態
    public class OnState implements LightState {@Overridepublic void switchState(Light light) {// 改變 Light 對象的狀態為 DimStatelight.setState(new DimState());System.out.println("Light is dimmed");}
    }// 創建具體狀態類:關閉狀態
    public class OffState implements LightState {@Overridepublic void switchState(Light light) {// 改變 Light 對象的狀態為 OnStatelight.setState(new OnState());System.out.println("Light is turned ON");}
    }// 創建具體狀態類:調暗狀態
    public class DimState implements LightState {@Overridepublic void switchState(Light light) {// 改變 Light 對象的狀態為 BlinkStatelight.setState(new BlinkState());System.out.println("Light is blinking");}
    }// 創建具體狀態類:閃爍狀態
    public class BlinkState implements LightState {@Overridepublic void switchState(Light light) {// 改變 Light 對象的狀態為 OffStatelight.setState(new OffState());System.out.println("Light is turned OFF");}
    }
    
  3. 在上下文類中使用狀態:最后,我們需要在上下文類中使用這些狀態。上下文類維護一個對狀態對象的引用,該引用可以在運行時更改。在我們的例子中,Light 類就是上下文類。

    // 創建上下文類:電燈
    public class Light {// Light 對象維護一個對狀態對象的引用private LightState state;public Light() {// 初始狀態為 OffStatethis.state = new OffState();}// 設置 Light 對象的狀態public void setState(LightState state) {this.state = state;}// 切換 Light 對象的狀態public void switchState() {state.switchState(this);}
    }
    
  4. 客戶端:通過客戶端測試

    public class Client {public static void main(String[] args) {// 創建一個 Light 對象Light light = new Light();// 切換 Light 對象的狀態light.switchState(); // 打開電燈light.switchState(); // 調暗電燈light.switchState(); // 電燈開始閃爍light.switchState(); // 關閉電燈}
    }
    

五、狀態模式的應用場景

狀態模式在許多場景中都非常有用,特別是當一個對象的行為取決于其狀態,并且它必須在運行時根據狀態改變其行為時。以下是一些常見的應用場景:

  1. 用戶界面(UI):在許多用戶界面中,元素的行為會根據其狀態(如禁用、選中、懸停等)而改變。狀態模式可以幫助我們管理這些狀態,并使狀態轉換的邏輯更加清晰。
  2. 游戲開發:在游戲開發中,角色的行為通常會根據其狀態(如站立、跑動、跳躍、攻擊等)而改變。使用狀態模式,我們可以為每種狀態創建一個狀態類,使得代碼更易于理解和維護。
  3. 工作流引擎:在工作流引擎中,任務的行為會根據其狀態(如新建、進行中、已完成等)而改變。狀態模式可以幫助我們管理這些狀態,并使狀態轉換的邏輯更加清晰。
  4. 網絡連接:網絡連接的行為會根據其狀態(如打開、關閉、等待等)而改變。狀態模式可以幫助我們管理這些狀態,并使狀態轉換的邏輯更加清晰。

六、小結

狀態模式是一種優秀的設計模式,適用于那些對象行為會隨著內部狀態變化而變化的情況。它通過將對象的狀態和行為分離,使得系統更加靈活、易于理解和擴展。

推薦閱讀

  1. 深入探究 Spring Boot Starter:從概念到實踐
  2. 深入理解 Java 中的 volatile 關鍵字
  3. OAuth 2.0:現代應用程序的授權標準
  4. Spring 三級緩存
  5. 深入了解 MyBatis 插件:定制化你的持久層框架

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

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

相關文章

snap和apt的區別簡單了解

Linux中沒有tree命令的時候提示安裝的時候出現了兩個命令,簡單看了看兩者有何區別(一般用apt就可以了): sudo snap install tree 和 sudo apt install tree 這兩個命令都是用來安裝 tree 命令行工具的,但它們使用的是不…

在線教育平臺,easyexcel使用案例

控制器 因為如何想要在讀數據的時候操作數據庫,就必須使用構造方法傳dao 或者service,因為這個不歸spring管理,不能自動注入,所以參數里需要傳遞service 或者 dao AutowiredIEduSubjectService subjectService;添加課程分類的方法…

Anaconda學習常見問題匯總

問題1:Fatal error in launcher: Unable to create process using ‘“d:\anaconda\isntall\envs\learn1\python.exe 在進行anaconda學習時,在控制臺輸入:pip list想要查看環境里的內容時發生錯誤: Fatal error in launcher: Un…

個人博客|PHP源碼|支持多國語言切換

一. 前言 今天小編給大家帶來了一款可學習,可商用的,支持多國語言的個人博客網站源碼,支持二開,無加密。此博客相當簡潔,也適合海外。詳細界面和功能見下面視頻演示。 如果您正好有此需求源碼,請聯系小編…

軟件資產管理系統:提升企業軟件資產透明度與合規性的終極解決方案!

在當今數字化轉型浪潮中,企業軟件資產管理的重要性日益凸顯。然而,傳統的手工管理方式往往效率低下,難以應對快速變化的軟件環境。SmartLic軟件資產管理系統應運而生,它以先進的技術手段,為企業提供全面的軟件資產管理…

開源自動化熱鍵映射工具autohotkey十大用法及精選腳本

AutoHotkey(AHK)是一款功能強大的熱鍵腳本語言工具,它允許用戶通過編寫腳本來自動化鍵盤、鼠標等設備的操作,從而極大地提高工作效率。以下是AutoHotkey的十大經典用法,這些用法不僅解放了用戶的雙手,還展示…

程序化交易廣告及其應用

什么是程序化交易廣告? 程序化交易廣告是以實時競價技術即RTB(real-time bidding)為核心的廣告交易方式。說到這里,你可能會有疑問:像百度搜索關鍵詞廣告還有百度網盟的廣告,不也是CPC實時競價的嗎&#x…

MDX的魔法:探索SQL Server中的多維表達式

📊 MDX的魔法:探索SQL Server中的多維表達式 在商業智能和數據分析領域,SQL Server提供了一種強大的工具來處理多維數據集,這就是多維表達式(Multidimensional Expressions,簡稱MDX)。MDX是一種…

論文學習_UVSCAN: Detecting Third-Party Component Usage Violations in IoT Firmware

論文名稱發表時間發表期刊期刊等級研究單位 Understanding the Security Risks Introduced by Third-Party Components in IoT Firmware 2024年IEEE TDSCCCF A佐治亞理工學院 1. 引言 研究背景:物聯網(IoT)已經無處不在,為我們…

HQChart報價列表高級應用教程7-走勢列數據對接

HQChart報價列表高級應用教程7-走勢列數據對接 走勢列小程序效果圖PC效果圖HQChart代碼地址走勢列類型配置走勢列數據格式示例走勢列 單獨使用一列顯示每個股票的走勢圖 小程序效果圖 PC效果圖 HQChart代碼地址 地址:github.com/jones2000/HQChart 走勢列類型 REPORT_COL…

[工業網絡] 模型建立

普渡大學ICS參考模型 普渡企業參考架構(PERA)是由西奧多J威廉姆斯(Theodore J. Williams)和普渡大學計算機集成制造工業大學聯盟的成員在1990年代開發的企業架構參考模型。該模型被ISA-99(現為ISA/IEC 62443&#xff…

使用EndNote在Word中插入參考文獻,并編輯參考文獻樣式方法

一、背景 在準備中期報告時,學校給的是Word模板,習慣了Latex排版和添加參考文獻的便利后,真不想用word寫東西。 之前投《機器人》期刊(被拒了)和準備開題的時候也是用word寫的,當時為方便添加參考文獻和定…

MyBatis 分頁插件 PageHelper 簡介

引言 PageHelper 是一款優秀的開源免費 MyBatis 分頁插件,它極大地簡化了分頁查詢的復雜性,支持多種主流數據庫如 MySQL、Oracle、MariaDB、DB2 等。本文將詳細介紹 PageHelper 的基本使用、配置參數、實現原理以及實際項目中的應用。 一、PageHelper …

Memcached中的CAS操作:確保數據一致性的原子武器

Memcached中的CAS操作:確保數據一致性的原子武器 在分布式緩存系統中,保持數據的一致性是一個重要而復雜的任務。Memcached作為一種高性能的分布式內存緩存系統,提供了一種稱為Compare-And-Swap(CAS)的操作&#xff0…

解決fastjson自動過濾null值

解決fastjson自動過濾null值 使用 SerializerFeature.WriteNullStringAsEmpty 解決 List<HistoryVector> historyVectors new ArrayList<>();HistoryVector historyVector new HistoryVector();historyVector.setInput("1");historyVector.setReason(&q…

不銹鋼酸退作業區2#冷線氧化鋯分析儀信號傳輸系統的優化

不銹鋼酸退作業區2#冷線氧化鋯分析儀信號傳輸系統的優化 一、項目提出前狀況: (一)不銹鋼酸退作業區2#冷線退火爐煙氣監測系統所使用的設備為橫河氧化鋯分析儀,此設備主要用于檢測退火爐內天然氣燃燒后煙氣成分中的氧含量值,此設備的檢測準確性直接影響產品質量,而且決定…

計算機操作系統部分選填及大題整理

并發和&#xff08; 共享 &#xff09; 是操作系統的兩個最基本的特征,&#xff08; 虛擬 &#xff09;和&#xff08; 異步 &#xff09; 是操作系統的重要特征&#xff0c;并發執行的程序失去可再現性現代操作系統的兩個基本特征是&#xff08;程序的并發執行&#xff09;和資…

萬界星空科技QMS系統:重塑質量管理新紀元

萬界星空科技QMS&#xff08;Quality Management System&#xff09;質量管理系統是一套全面、高效的質量管理工具&#xff0c;旨在幫助企業提升產品質量、優化生產流程、降低質量成本。該系統具備多個具體功能模塊&#xff0c;以下是對其主要功能模塊的詳細介紹&#xff1a; 一…

Java中的線程安全問題及解決方案

Java中的線程安全問題及解決方案 大家好&#xff0c;我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01; 在多線程編程中&#xff0c;線程安全是一個至關重要的概念。當多個線程同時訪…

JPA -EntityGraph 實體圖失效問題

jpa查詢方便了查詢&#xff0c;但是有時會也會影響性能&#xff0c;有時候會加載深度過深和加載了不需要但非常占用內存的數據。所以此時可以使用實體圖&#xff0c;懶加載或者不加載某些數據。這些數據可以是不同層級上的。 但是最近發現代碼中出現實體圖失效的問題。查詢資料…