Java設計模式之《命令模式》

目錄

1、介紹

1.1、命令模式定義

1.2、對比

1.3、典型應用場景

2、命令模式的結構

2.1、組成部分:

2.2、整體流程

3、實現

3.1、沒有命令模式

3.2、命令模式寫法

4、命令模式的優缺點


前言

java設計模式分類:


1、介紹

1.1、命令模式定義

?????命令模式(Command Pattern)是一種行為型設計模式,又叫動作模式或事務模式

????????它將請求(命令)封裝成對象,使得可以用不同的請求對客戶端進行參數化具體的請求可以在運行時更改、排隊或記錄,它將發出者和接收者解耦(順序:發出者-->命令-->接收者)。

總結:

????????把請求的動作和請求的接收者進行解耦,讓你能將動作封裝成對象,再傳遞、存儲、撤銷或排隊等。

1.2、對比

狀態模式:

Context(電梯)-- 持有當前狀態 --> State(狀態接口)-- 實現 --> OpenState, RunState等

命令模式:

1.3、典型應用場景

1、Runnable接口:

????????Java中的Runnable接口就是一個典型的命令模式的應用。Runnable接口封裝了需要執行的任務,然后可以交給線程去執行


2、Timer和TimerTask類:

????????這兩個類用于定時任務調度,TimerTask類封裝了要執行的任務,然后由Timer類作為調用者執行這些任務。


3、Statement接口:

????????在Java中與數據庫交互時,SQL語句被封裝成Statement對象,然后由數據庫驅動程序執行相應的命令。

生活示例:

1、 餐廳點餐:

????????在一家餐廳中,服務員充當調用者,廚師充當接收者,菜品可以作為具體命令。當顧客想點菜時,服務員會將顧客的需求封裝成一個命令對象,并傳遞給廚師。廚師根據命令對象中的信息來完成相應的烹飪工作。這樣,顧客和廚師之間不需要直接溝通,而是通過命令對象來實現點餐和烹飪的解耦。


2、遙控器控制家電:

????????拿電視遙控器舉例,遙控器是調用者,電視是接收者。每個按鍵都可以看作是一個具體命令,例如音量加、音量減、切換頻道等。

????????當用戶按下某個按鍵時,遙控器會發送相應的命令給電視,然后電視根據命令執行相應的操作,如增加音量、減小音量或切換頻道。


2、命令模式的結構

2.1、組成部分:

  1. Command(命令接口/抽象類)?聲明execute()方法。
  2. ConcreteCommand(具體命令)?實現Command,并持有Receiver引用,把請求操作的接收者封裝進來,調用接收者的方法。
  3. Receiver(接收者)?真正執行業務邏輯的對象。
  4. Invoker(調用者)?有個成員變量保存Command,并執行command.execute()
  5. Client(客戶端):?組裝命令、接收者、并給調用者下令。

2.2、整體流程

所有的“做某件事”,都變成訂單(命令對象)Waiter只“發訂單”,Chef只“實現訂單”:

如下圖所示:

????????命令模式,把“執行動作”的代碼封裝成對象。Waiter(服務員)不需要知道每個命令詳情,只要保存一份“命令單子”,然后調用它的執行方法即可。


3、實現

假設你在飯店點菜。

  • 你(Client 客戶端):我要點“宮保雞丁”。
  • 服務員(Invoker 調用者):拿到菜單,把點菜單(訂單)交給廚房。
  • 訂單(Command 命令對象):訂單上寫著“做宮保雞丁”。
  • 廚師(Receiver 接收者):收到訂單,立刻開始炒菜。

這樣,服務員并不需要會做菜,他只要拿訂單就行了。

3.1、沒有命令模式

你直接告訴服務員 “去讓張師傅做宮保雞丁”:

代碼如下所示:

// 直接耦合
public class Waiter {private Chef chef = new Chef();public void orderGongBaoChicken() {chef.makeGongBaoChicken();}
}public class Chef {public void makeGongBaoChicken() {System.out.println("炒宮保雞丁!");}
}
// 調用
Waiter waiter = new Waiter();
waiter.orderGongBaoChicken();

3.2、命令模式寫法

1. 命令接口

public interface Command {void execute();   // 執行命令void undo();      // 撤銷命令(可選)
}
  • 這里的Command相當于“點菜單的模板”,所有的點菜單都要有一個execute方法。

2. 接收者(Receiver)——廚師

public class Chef {public void makeGongBaoChicken() {System.out.println("廚師:炒宮保雞丁!");}public void makeFriedRice() {System.out.println("廚師:炒蛋炒飯!");}
}
  • Chef能夠真的炒不同的菜。

3. 具體命令(ConcreteCommand)——不同的訂單

public class GongBaoChickenCommand implements Command {private Chef chef;public GongBaoChickenCommand(Chef chef) {this.chef = chef;}@Overridepublic void execute() {chef.makeGongBaoChicken();}@Overridepublic void undo() {System.out.println("取消宮保雞丁!");}
}public class FriedRiceCommand implements Command {private Chef chef;public FriedRiceCommand(Chef chef) {this.chef = chef;}@Overridepublic void execute() {chef.makeFriedRice();}@Overridepublic void undo() {System.out.println("取消蛋炒飯!");}
}
  • 每個命令就是一張“點菜單”,知道自己要交給哪個廚師(Receiver)。

4、調用者(Invoker)服務員

public class Waiter {private Command command;public void setCommand(Command command) {this.command = command;}public void placeOrder() {// 點菜command.execute();}public void cancelOrder() {// 撤銷點菜command.undo();}
}

5、客戶端組裝

public class Customer {public static void main(String[] args) {Chef chef = new Chef();Command gongBaoChicken = new GongBaoChickenCommand(chef);Command friedRice = new FriedRiceCommand(chef);Waiter waiter = new Waiter();// 點宮保雞丁waiter.setCommand(gongBaoChicken);waiter.placeOrder();// 點蛋炒飯waiter.setCommand(friedRice);waiter.placeOrder();// 撤銷剛才的蛋炒飯waiter.cancelOrder();}
}

輸出:

廚師:炒宮保雞丁!
廚師:炒蛋炒飯!
取消蛋炒飯!

有上述示例可知命令模式的功能:

  • 解耦:Waiter只需要認識命令Command,不用知道Chef做什么。
  • 追加功能:要新增一道菜,只要做一個新的Command類即可,Waiter不用改。
  • 支持隊列、日志、撤銷:命令對象能被存儲、排隊,可以撤銷。

4、命令模式的優缺點

1、優點:

徹底解耦“請求者”與“執行者”,調用者無需知道接收者是啥

請求可以參數化(每個對象帶不同接收者和參數)。

請求可以放隊列、做日志,如事務撤銷與恢復、任務隊列。

增加新命令類非常方便。

2、缺點:

類的數量可能會增多(每種命令都要實現 Command 接口)。


總結

????????命令模式適用于需要將請求封裝成對象,實現請求發出者和接收者之間的解耦,并支持撤銷隊列化延遲執行的場景。它雖然可以提高系統的可擴展性和靈活性,但是需要權衡額外的開銷和復雜性。


參考文章:

1、設計模式第19講——命令模式(Command)-CSDN博客文章瀏覽閱讀1.1w次,點贊38次,收藏174次。命令模式是一種行為設計模式,它將請求封裝為對象,使發出者和接收者解耦。文章介紹了命令模式的角色(抽象命令、具體命令、接收者和調用者),優缺點以及在餐廳點餐和Java場景中的應用,還提供了代碼實現示例。 https://blog.csdn.net/weixin_45433817/article/details/131465270?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522d919eba72e6dd9b4ef68572ad0a68137%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=d919eba72e6dd9b4ef68572ad0a68137&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-131465270-null-null.142^v102^control&utm_term=%E5%91%BD%E4%BB%A4%E6%A8%A1%E5%BC%8F&spm=1018.2226.3001.4187

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

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

相關文章

【動態規劃算法】路徑問題

什么是動態規劃算法動態規劃(Dynamic Programming,簡稱 DP)是一種通過分解復雜問題為重疊子問題,并存儲子問題的解以避免重復計算,從而高效求解具有特定性質(重疊子問題、最優子結構)問題的算法…

Java基本技術講解

一、基礎語法三要素 暫時無法在飛書文檔外展示此內容 🔑 黃金法則?:每個變量都要聲明類型!二、程序邏輯控制(游戲行為核心) 條件判斷:if-else - “岔路口選擇” // 撿到金幣邏輯 if (isTouching(Coin.clas…

【網絡基礎2】路由器的 “兩扇門”:二層接口和三層接口到底有啥不一樣?

目錄 前言:路由器不是只有 “插網線的口” 一、先搞懂一個基礎:路由器是 “網絡交通樞紐” 二、二層接口:“小區內部的單元門”,只認 “住戶身份證” 1. 啥是二層接口? 2. 用 “小區內部串門” 理解二層接口 步驟 1:手機打包數據,寫上 “收件人身份證” 步驟 2:二…

MLIR TableGen

簡介 TableGen 是一種領域特定語言(DSL),TableGen 的設計目標是允許編寫靈活的描述,并將記錄的通用特性提取出來,從而減少重復代碼并提高代碼的可維護性。 TableGen的工作流程: 前端解析: Ta…

2、docker容器命令 | 信息查看

1、命令總覽命令作用docker ps查看運行中的容器(-a查看所有容器)docker logs [CONTAINER]查看容器日志(-f實時追蹤日志)docker inspect [CONTAINER]查看容器詳細信息(JSON格式)docker stats [CONTAINER]實時…

【MySQL】MySQL中鎖有哪些?

一、按照粒度分類: 粒度越小,并發度越高,鎖開銷越大。 1.全局鎖: 作用: 鎖定整個MySQL實例(所有數據庫)。適用場景: 全庫邏輯部分。(確保備份期間數據的一致性。)實現方式: 通過 FLUSH TABLES W…

語義分割--deeplabV3+

根據論文網絡結構圖講一下:網絡分為兩部分:encoder和decoder部分。 Encoder:DCNN就是主干網絡,例如resnet,Xception,MobileNet這些(主干網絡也要使用空洞卷積),對dcnn的結…

Azure DevOps 中的代理

必知詞匯 深入研究 Azure DevOps 中的代理之前需要掌握的基本概念: 代理:Azure DevOps 中的代理是一個軟件組件,負責執行流水線中的任務和作業。這可能包括數據中心內的物理服務器、本地或云端托管的虛擬機,甚至是容器化環境。這些代理可以在各種操作系統和環境中運行,例如…

AUTOSAR進階圖解==>AUTOSAR_SRS_ADCDriver

AUTOSAR ADC驅動詳解 基于AUTOSAR標準的ADC驅動模塊需求規范分析目錄 ADC驅動模塊概述 關鍵概念定義 ADC驅動架構 ADC驅動在AUTOSAR分層架構中的位置ADC驅動的主要職責 ADC驅動配置結構 通用配置(AdcGeneral)硬件單元配置(AdcHwUnit)通道配置(AdcChannel)通道組配置(AdcChanne…

寶馬集團與SAP聯合打造生產物流數字化新標桿

在德國雷根斯堡的寶馬工廠,每57秒就有一輛新車下線。這座工廠不僅是汽車制造的基地,更是寶馬集團向SAP S/4HANA云平臺轉型的先鋒項目。通過“RISE with SAP”計劃,寶馬將該工廠的運營系統全面遷移至SAP S/4HANA Cloud Private Edition&#x…

Go 語言實戰:構建一個高性能的 MySQL + Redis 應用

引言:為什么是 Go MySQL Redis?在現代后端技術棧中,Go MySQL Redis 的組合堪稱“黃金搭檔”,被廣泛應用于各種高并發業務場景。Go 語言:以其卓越的并發性能、簡潔的語法和高效的執行效率,成為構建高性能…

Excel超級處理器,多個word表格模板中內容提取到Excel表格中

在職場中,很多人習慣在word里插入表格,設計模板,填寫內容,一旦有多個word文件需要整理在excel表格中,最常見的工作方式就是每個word文件打開,復制,粘貼到excel表格里,這樣的工作方式…

前端工程化:ES6特性

本文為個人學習筆記整理,僅供交流參考,非專業教學資料,內容請自行甄別 文章目錄一、let與var1.1、越獄問題1.2、變量的重復聲明1.3、變量提升問題二、解構2.1、數組解構2.2、對象解構2.3、方法解構三、鏈判斷四、參數默認值五、箭頭函數六、模…

大屏項目展示

一、項目克隆與基礎操作 我們參考的項目 互聯網設備可視化平臺---IofTV-Screen: ??一個基于 vue、datav、Echart 框架的物聯網可視化(大屏展示)模板,提供數據動態刷新渲染、屏幕適應、數據滾動配置,內部圖表自由替換、Mixins注入等功能,持續更新.... 將次項目克隆到本…

基于R語言地理加權回歸、主成份分析、判別分析等空間異質性數據分析實踐技術應用

在自然和社會科學領域有大量與地理或空間有關的數據,這一類數據一般具有嚴重的空間異質性,而通常的統計學方法并不能處理空間異質性,因而對此類型的數據無能為力。以地理加權回歸為基礎的一系列方法:經典地理加權回歸,…

【Flask 基礎 ①】 | 路由、參數與模板渲染

0 序言 Flask 是 Python 生態中一款輕量級 Web 框架,以簡潔、靈活著稱。 學習 Flask 的意義在于: 快速開發:通過少量代碼即可搭建功能完整的 Web 應用;理解原理:其設計清晰體現了 Web 框架的核心邏輯,如路由…

wordpress登陸前登陸后顯示不同的頂部菜單

在WordPress中讓“未登錄”和“已登錄”用戶看到不同的頂部菜單,最干凈、最安全、最可維護的做法是: 在同一個菜單位置(themelocation)里,根據is_user_logged_in()動態切換菜單。 下面給出三種常見實現方式,按推薦程度排序。任選…

【昇騰推理PaddleOCR】生產級部署方式

已知的在昇騰上推理Paddle OCR有三種方法: 概要: PyTorch官方提供了昇騰插件包,安裝后雖然可以支持PytorchOCR和PaddlePaddle的推理任務,但性能較低。換句話說,PaddlePaddle框架層面支持了昇騰,但具體到某個…

LangChain摘要記憶組件的使用與解析

01. 摘要記憶組件的類型 在 LangChain 中使用緩沖記憶組件要不就保存所有信息(占用過多容量),要不就保留最近的記憶信息(丟失太多重要信息),那么有沒有一種情況是既要又要呢? 所以折中方案就出…

NAT與智能選路

1、NAT 基礎概念核心作用:私網地址無法在 Internet 上直接使用和分配,NAT 通過將私有地址與公有地址及端口進行轉換,實現私網與公網的通信。轉換示例:內網用戶(10.1.1.1)訪問外網 FTP Server(12…