設計模式精講 Day 20:狀態模式(State Pattern)

【設計模式精講 Day 20】狀態模式(State Pattern)


文章標簽

設計模式, 狀態模式, Java開發, 面向對象設計, 軟件架構, 設計模式實戰, Java應用開發


文章簡述

狀態模式是行為型設計模式中的重要一員,用于管理對象在不同狀態下的行為變化。在實際項目中,狀態模式能夠有效解耦狀態邏輯,提升系統的可維護性和擴展性。本文作為“設計模式精講”系列的第20天,深入講解了狀態模式的核心思想、實現方式和實際應用場景。文章通過完整的Java代碼示例,展示了如何在具體業務場景中使用狀態模式優化系統結構,并結合真實案例分析其優勢與局限性。無論你是初學者還是有經驗的開發者,這篇文章都將幫助你掌握狀態模式的設計精髓并應用于實際項目中。


【設計模式精講 Day 20】狀態模式(State Pattern)

開篇:狀態模式的核心思想與應用價值

今天是“設計模式精講”系列的第20天,我們聚焦于狀態模式(State Pattern)。狀態模式是一種行為型設計模式,它允許一個對象在其內部狀態改變時改變其行為,使得對象的行為與其狀態保持一致。

在軟件開發中,很多業務場景需要根據不同的狀態執行不同的操作,例如訂單狀態從“待支付”變為“已支付”,或者用戶狀態從“未登錄”變為“已登錄”。如果直接使用條件判斷來處理這些狀態轉換,會導致代碼臃腫、難以維護。而狀態模式通過將狀態封裝為獨立的對象,實現了狀態與行為的解耦,使系統更加靈活、可擴展。

本篇文章將從模式定義、結構、適用場景、實現方式、工作原理、優缺點分析、案例分析等多個維度,全面解析狀態模式,并提供完整可運行的Java代碼示例,幫助你真正掌握這一設計模式。


模式定義

1.1 正式定義

狀態模式(State Pattern)是一種行為型設計模式,它允許一個對象在其內部狀態改變時改變其行為。該模式將狀態相關的行為封裝到不同的狀態類中,使得對象的行為隨著狀態的變化而變化,而無需顯式的條件判斷語句。

1.2 核心思想

  • 狀態封裝:每個狀態由一個獨立的類表示,封裝對應的行為。
  • 狀態切換:對象的狀態可以通過調用方法進行切換,而不會影響其他部分。
  • 行為委托:對象的行為由當前狀態對象負責,而非自身。

模式結構

2.1 UML 類圖說明(文字描述)

狀態模式包含以下幾個關鍵角色:

角色說明
Context(上下文)維護當前狀態對象,并將請求委托給當前狀態對象處理。
State(狀態接口)定義所有具體狀態類需要實現的方法。
ConcreteStateA / B(具體狀態類)實現 State 接口,定義在特定狀態下應執行的行為。

2.2 示例結構說明

  • Context 類持有 State 接口的引用。
  • State 是抽象類或接口,定義了 handle() 方法。
  • ConcreteStateAConcreteStateB 分別實現 Statehandle() 方法,定義各自的行為。

適用場景

場景說明
對象行為依賴于其狀態當對象的行為隨狀態變化時,適合使用狀態模式。
多個條件分支導致代碼復雜使用狀態模式可以避免大量的 if-elseswitch-case 判斷。
狀態轉換頻繁在狀態頻繁切換的場景下,狀態模式能提高代碼可讀性和可維護性。
需要擴展新狀態新增狀態只需添加新的狀態類,無需修改現有代碼。

實現方式

3.1 Java 代碼實現

以下是一個基于狀態模式的簡單示例,模擬一個“訂單狀態機”的行為。

3.1.1 定義狀態接口
// State.java
public interface State {void handle(OrderContext context);
}
3.1.2 具體狀態類
// PendingState.java
public class PendingState implements State {@Overridepublic void handle(OrderContext context) {System.out.println("訂單處于待支付狀態");context.setState(new PaidState());}
}// PaidState.java
public class PaidState implements State {@Overridepublic void handle(OrderContext context) {System.out.println("訂單已支付");context.setState(new ShippedState());}
}// ShippedState.java
public class ShippedState implements State {@Overridepublic void handle(OrderContext context) {System.out.println("訂單已發貨");context.setState(new DeliveredState());}
}// DeliveredState.java
public class DeliveredState implements State {@Overridepublic void handle(OrderContext context) {System.out.println("訂單已簽收");context.setState(new CompletedState());}
}// CompletedState.java
public class CompletedState implements State {@Overridepublic void handle(OrderContext context) {System.out.println("訂單已完成");}
}
3.1.3 上下文類
// OrderContext.java
public class OrderContext {private State state;public OrderContext() {this.state = new PendingState(); // 初始狀態為待支付}public void setState(State state) {this.state = state;}public void handle() {state.handle(this);}
}
3.1.4 測試類
// StatePatternTest.java
public class StatePatternTest {public static void main(String[] args) {OrderContext order = new OrderContext();order.handle(); // 待支付order.handle(); // 已支付order.handle(); // 已發貨order.handle(); // 已簽收order.handle(); // 已完成}
}

輸出:

訂單處于待支付狀態
訂單已支付
訂單已發貨
訂單已簽收
訂單已完成

工作原理

狀態模式通過將狀態相關的邏輯封裝到各個狀態類中,使得上下文對象(如 OrderContext)不再需要知道具體的業務邏輯,而是將請求委托給當前狀態對象處理。

當狀態發生變化時,只需要修改上下文對象持有的狀態引用即可,無需修改原有代碼。這種機制符合開閉原則,提高了系統的可擴展性和可維護性。


優缺點分析

優點缺點
解耦狀態邏輯:狀態行為被封裝,避免了大量條件判斷。增加類的數量:每個狀態都需要一個類,可能導致類爆炸。
易于擴展:新增狀態只需添加新類,無需修改已有代碼。狀態切換復雜:狀態之間的轉換可能需要額外的邏輯處理。
符合單一職責原則:每個狀態類只關注自己的行為。學習成本較高:對于新手來說,理解狀態模式的結構有一定難度。

案例分析:訂單狀態管理

4.1 問題描述

某電商平臺的訂單系統中,訂單狀態包括:待支付、已支付、已發貨、已簽收、已完成。每次狀態變更都需要觸發相應的業務邏輯,比如發送通知、更新庫存等。但目前的實現方式是通過大量 if-else 判斷,導致代碼冗長、難以維護。

4.2 解決方案

采用狀態模式重構訂單狀態管理邏輯,將每個狀態的行為封裝為獨立的類,通過上下文對象統一管理狀態轉換。

4.2.1 改進后的代碼結構
  • OrderContext:管理訂單狀態
  • State 接口:定義狀態處理方法
  • PendingStatePaidState 等:分別實現狀態行為
4.2.2 優勢體現
  • 可維護性提升:新增狀態只需添加新類
  • 可讀性增強:狀態行為清晰明了
  • 可測試性強:每個狀態類可單獨測試

與其他模式的關系

模式關系說明
策略模式(Strategy Pattern)類似但用途不同策略模式用于替換算法,狀態模式用于控制行為變化
命令模式(Command Pattern)可組合使用命令模式封裝請求,狀態模式控制行為,二者可協同工作
工廠模式(Factory Pattern)可配合使用工廠模式可用于創建狀態對象,簡化狀態初始化過程

總結

5.1 本日學習要點

  • 狀態模式的核心思想是將對象的狀態行為封裝為獨立的類。
  • 通過上下文對象統一管理狀態轉換,實現行為與狀態的解耦。
  • 狀態模式適用于多狀態、行為變化頻繁的場景。
  • 通過完整 Java 示例,展示了狀態模式的實現方式和實際應用。
  • 狀態模式與策略模式、命令模式等存在相似之處,但在應用場景上有明顯區別。

5.2 下一日預告

明天我們將進入“設計模式精講”系列的第21天,主題為【設計模式精講 Day 21】策略模式(Strategy Pattern)。我們將探討如何通過策略模式實現算法的動態切換,提升系統的靈活性和可擴展性。敬請期待!


進一步學習資料

  1. 《設計模式:可復用面向對象軟件的基礎》 —— GoF 經典著作
  2. 狀態模式 - Wikipedia
  3. Java 設計模式之狀態模式詳解
  4. Spring 框架中的狀態模式應用
  5. 狀態模式 vs 策略模式對比

【設計模式精講 Day 20】狀態模式(State Pattern) 已完成,歡迎轉發、收藏、評論交流。

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

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

相關文章

橋島隧大型工程 3D 可視化監測平臺

深中通道作為“橋、島、隧、水下互通”一體化跨海集群工程,其復雜結構帶來高強度監測難題。借助圖撲軟件 HT 實現深中通道的建設與運營的數字化升級,為交通基建行業邁向高效、智能的未來提供了有力支撐。 圖撲自主研發的 HT for Web 產品搭建深中通道-橋…

基于SpringBoot和Leaflet的區域沖突可視化系統(2025企業級實戰方案)

摘要 在全球地緣沖突與應急事件頻發的2025年,區域態勢可視化系統成為政府及企業的決策剛需。本文提出基于??SpringBoot 3.2??后端與??Leaflet 1.9.5??前端的沖突可視化解決方案,融合多源異構數據(衛星影像、輿情熱力、設施狀態&…

[密碼學實戰]國密TLCP協議報文解析代碼實現(三十)

[密碼學實戰]國密TLCP協議報文解析代碼實現(三十) 本文將深入解析國密TLCP協議報文結構,提供完整的Java實現代碼,幫助開發者理解TLCP協議在國密環境下的通信機制和安全性設計。 一、國密TLCP協議概述 TLCP(Transport Layer Cryptographic Protocol)是基于國密算法(SM2/…

[Python] -基礎篇5-玩轉Python內置數據結構:列表、元組、字典與集合

Python 是一門以簡潔優雅著稱的編程語言,其中內置的數據結構為日常編程提供了強大支持。本文將系統介紹 Python 中四大核心數據結構:列表(list)、元組(tuple)、字典(dict)與集合(set),并配以實用示例,幫助讀者全面掌握其用法及適用場景。 一、列表(List):可變序…

技術突破與落地應用:端到端 2.0 時代輔助駕駛TOP10 論文深度拆解系列【第八篇(排名不分先后)】

HiP-AD: Hierarchical and Multi-Granularity Planning with Deformable Attention for Autonomous Driving in a Single Decoder GitHub地址:?https://github.com/nullmax-vision/HiP-AD? 在自動駕駛技術飛速發展的今天,端到端自動駕駛(E…

transformer位置編碼研究相關的綜述、論文

一、權威綜述 《利用位置編碼實現長度外推》 (騰訊云開發者社區, 2024) 系統分析絕對/相對位置編碼(APE/RPE)在長序列外推中的技術演進,涵蓋RoPE、Alibi、Xpos等優化方案,討論位置插值、NTK-aware縮放等擴展…

垂直領域AI智能體開發指南:用Bright Data MCP接入智能體攻克數據難關

垂直領域AI智能體開發指南:用Bright Data MCP接入智能體攻克數據難關 一、智能體時代的數據困局1.1 AI智能體的爆發式增長1.2 開發者遭遇的"數據瓶頸" 二、Bright Data MCP:智能體的數據引擎2.1 重新定義數據獲取方式2.2 支持的核心場景2.3 四…

Stable Diffusion 項目實戰落地:從0到1 掌握ControlNet 第三篇: 打造光影字形的創意秘技-文字與自然共舞

上一篇,我們一起玩轉了 野外光影字,是不是被那種自然和光影交織的效果驚艷到啦? 如果你錯過了那篇文章,別擔心,趕緊點這里補課:Stable Diffusion 項目實戰落地:從0到1 掌握ControlNet:打造光影文字 第二篇 - 野外光影字。 今天,我們將一起做一個 生成的嵌入式文字【…

CppCon 2018 學習:Feather: A Modern C++ Web Development Framework

你這段內容羅列的是 Web 開發中的幾個基礎概念和組成模塊,下面我逐一用中文進行解釋,并理清它們之間的關系: 基礎概念說明 1. HTTP Server(HTTP服務器) 是一個監聽 HTTP 請求并返回響應的程序。主要功能&#xff1a…

武漢大學機器人學院啟航:一場顛覆性的產教融合實驗,如何重塑中國智造未來?

當百年學府按下“產業加速鍵”,教育革命的號角已經吹響 2025年7月,武漢大學一紙公告震動教育界與科技圈——成立機器人學院,攜手小米、宇樹等硬科技領軍企業,聘請10位產業教授入駐。這絕非一次常規的校企合作,而是一場…

QT記事本4——下拉框修改值后解決亂碼問題

下拉框修改值后解決亂碼問題 void Widget::onCurrentIndexChanged(int index) {qDebug()<<index;//索引從0開始qDebug()<<ui->comboBox->currentText();//切換編碼時&#xff0c;首先清空當前的文本框ui->textEdit->clear();if(file.isOpen()){//僅在…

““ ‘‘ C++

在C中&#xff0c;"" 和 的含義完全不同&#xff0c;只有""是空字符串&#xff0c;而既不是空字符串&#xff0c;也不能表示空字符&#xff0c;具體區別如下&#xff1a; 1. 雙引號 ""&#xff1a;空字符串字面量 類型&#xff1a;const char…

電腦遠程控制另一臺電腦無法連接怎么辦

電腦遠程控制另一臺電腦無法連接怎么辦&#xff1f;遠程桌面連接是遠程管理另一臺計算機時比較常用的方式&#xff0c;在進行電腦遠程控制時&#xff0c;無法連接是常見的問題&#xff0c;以下將從多個方面分析原因并提供解決方法。如果涉及無公網IP目標主機需要遠程桌面連接的…

springboot3.2/3.4+rocketmq5.3.3測試程序的基本例子

想測試下springboot新版中與rocketmq5.3.3的配置使用&#xff0c;今天嘗試了下&#xff0c;記錄如下&#xff1a; 1、首先springboot使用3.2.7&#xff0c;rocketmq使用5.3.3&#xff0c;且使用docker部署rocketmq。 docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/do…

深入剖析AI大模型:TensorFlow

今天來聊一下TensorFlow&#xff0c;任何一門技術我建議還是從它出現的背景開始。因為你這就知道它存在的原因是什么。2015 年&#xff0c;Google 開源了深度學習框架 TensorFlow&#xff0c;一經推出便在學術界和工業界引起巨大反響。當時&#xff0c;深度學習模型的復雜度與日…

【數字后端】- tcbn28hpcplusbwp30p140,標準單元庫命名含義

tcbn28: 代表工藝類型是臺積電28nm工藝hpcplus: 代表工藝平臺是HPC BWP: 其中B代表標準單元的類型是 “standard” base cell&#xff1b;W代表N-well 工藝&#xff0c;放置在 P-substrate上&#xff1b;P表示該 cell 使用的是 P-type transistor layout orientation&#xff1…

KNN算法詳解及Scikit-learn API使用指南

一、KNN算法介紹 K最近鄰(K-Nearest Neighbor, KNN)算法是機器學習中最簡單、最直觀的分類算法之一。它既可以用于分類問題&#xff0c;也可以用于回歸問題。KNN是一種基于實例的學習(instance-based learning)或懶惰學習(lazy learning)算法&#xff0c;因為它不會從訓練數據…

【PMP】項目管理入門:從基礎到環境的體系化拆解

不少技術管理者都有過這樣的困惑&#xff1a; 明明按流程做了項目管理&#xff0c;結果還是延期、超預算&#xff1f;需求變更多到炸&#xff0c;到底是客戶無理還是自己沒管好&#xff1f;跨部門協作像“推皮球”&#xff0c;資源總不到位&#xff1f; 其實&#xff0c;項目失…

【Web前端】簡易輪播圖顯示(源代碼+解析+知識點)

一、簡易輪播圖源代碼 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>簡易輪播圖顯示</title><style type"text/css">*{margin: 0 auto;padding: 0;/* 全局重置邊距 */}p{text-align: center;fon…

電機試驗平臺的用途及實驗范圍

電機試驗平臺是一種專門設計用來對各種類型的電機進行測試和分析的設備。在現代工業中&#xff0c;電機作為驅動力的重要組成部分&#xff0c;在各個領域發揮著至關重要的作用。而為了確保電機的性能、效率和可靠性達到最佳水平&#xff0c;需要進行各種試驗和測試。電機試驗平…