設計模式使用場景實現示例及優缺點(行為型模式——命令模式)

從前,在一個美麗而神秘的王國里,住著一位智慧而仁慈的國王。他不僅以其公正和睿智著稱,還因為他對知識的熱愛和追求。他的王國繁榮昌盛,人們生活幸福安康。但即便如此,國王知道,要維持這種繁榮與和平,需要不斷學習和改進。

一天,國王召集了他的三位最信任的大臣:戰士將軍艾里克、魔法師梅琳達和工程師菲利克斯。他告訴他們,他聽說在遙遠的東方,有一種古老的智慧,名為“命令模式”。這種智慧可以將復雜的請求轉化為簡潔有力的命令,從而使整個王國的管理更加高效。

將軍艾里克是個果敢的人,他立刻提議親自前往東方尋找這種智慧。梅琳達和菲利克斯也表示愿意一同前往。于是,三人開始了他們的冒險旅程。

他們跋山涉水,穿越了茂密的森林和險峻的山脈,終于來到了一個傳說中的智慧之城。在那里,他們遇到了一位古老的智者。智者同意教他們命令模式的秘密,但前提是他們必須通過三個試煉。

第一個試煉是智慧試煉。智者給他們出了一個難題:如何將一個復雜的請求簡化為一個簡單的命令?梅琳達用她的魔法力量,展示了如何將繁瑣的法術步驟封裝在一個簡單的魔法卷軸中,完美地解決了難題。

第二個試煉是勇氣試煉。智者讓他們面對一頭兇猛的巨龍,并要求他們在不傷害巨龍的情況下,取回巨龍守護的寶物。將軍艾里克利用他的勇氣和智慧,使用命令模式中的“請求撤銷”原理,指揮巨龍一步步離開寶物,最終成功取回寶物。

最后一個試煉是團隊合作試煉。智者讓他們設計一個系統,使得城市中的每個居民都能輕松發出請求,并能得到迅速響應。菲利克斯用他的工程知識,設計了一套基于命令模式的系統,每個請求都被封裝成一個對象,并根據需要進行排隊、記錄和執行。三人齊心協力,完美地通過了試煉。

智者對他們的表現非常滿意,將命令模式的所有秘密傳授給了他們。三人帶著智慧的結晶,回到了王國。他們將命令模式應用到王國的各個領域,管理變得更加高效,人民的生活也更加便利。

從那以后,這個王國不僅以其繁榮與和平著稱,還以其先進的管理系統聞名于世。而將軍艾里克、魔法師梅琳達和工程師菲利克斯,也被人們稱頌為智慧與勇氣的化身。他們的冒險故事,也成為了世代相傳的美談。

命令模式(Command Pattern)

命令模式(Command Pattern)是一種行為設計模式,它將請求封裝成一個對象,從而使你可以用不同的請求對客戶進行參數化,隊列或記錄請求日志,以及支持可撤銷的操作。在命令模式中,請求被封裝為一個對象,這個對象包含了執行請求的方法,以及所有必要的參數。這樣,客戶端只需創建并傳遞一個命令對象給調用者,而無需關心具體的實現細節。

核心組件

  • Command(命令):定義了執行請求的接口。
  • ConcreteCommand(具體命令):實現了命令接口,負責調用請求的接收者來執行請求。
  • Receiver(接收者):知道如何實施與執行一個請求相關的操作。
  • Invoker(調用者):要求命令執行請求的對象。
  • Client(客戶端):創建具體命令對象并設置其接收者。

適用場景

  1. 需要將請求發送者和請求接收者解耦
    • 命令模式允許請求發送者和接收者獨立變化,互不影響。
  2. 需要支持命令的排隊、記錄請求日志、撤銷操作等功能
    • 命令模式可以輕松地擴展這些功能。
  3. 需要將一組操作組合在一起形成一個命令
    • 命令模式可以將多個操作封裝成一個命令對象。

實現實例

基于命令模式(Command Pattern)的遙控器控制家電的系統。

命令接口(Command Interface)

定義了執行命令的方法。

public interface Command {void execute(); // 執行命令的方法
}

具體命令(Concrete Command)

實現了命令接口,負責調用接收者執行具體操作。

LightOnCommand
public class LightOnCommand implements Command {private Light light; // 接收者對象public LightOnCommand(Light light) {this.light = light;}public void execute() {light.turnOn(); // 調用接收者的方法}
}
LightOffCommand
public class LightOffCommand implements Command {private Light light; // 接收者對象public LightOffCommand(Light light) {this.light = light;}public void execute() {light.turnOff(); // 調用接收者的方法}
}

接收者(Receiver)

知道如何實施與執行請求相關的操作。

public class Light {public void turnOn() {System.out.println("Light is on"); // 執行打開燈的操作}public void turnOff() {System.out.println("Light is off"); // 執行關閉燈的操作}
}

調用者(Invoker)

要求命令執行請求的對象。

public class RemoteControl {private Command command; // 當前命令對象public void setCommand(Command command) {this.command = command; // 設置命令對象}public void pressButton() {command.execute(); // 執行當前命令}
}

客戶端代碼(Client Code)

演示如何使用命令模式。

public class Client {public static void main(String[] args) {Light livingRoomLight = new Light(); // 創建接收者對象Command lightOn = new LightOnCommand(livingRoomLight); // 創建打開燈的命令Command lightOff = new LightOffCommand(livingRoomLight); // 創建關閉燈的命令RemoteControl remoteControl = new RemoteControl(); // 創建調用者對象remoteControl.setCommand(lightOn); // 設置打開燈的命令remoteControl.pressButton(); // 執行打開燈的命令remoteControl.setCommand(lightOff); // 設置關閉燈的命令remoteControl.pressButton(); // 執行關閉燈的命令}
}

解釋

  • 命令接口(Command Interface):定義了 execute() 方法,所有具體命令類都必須實現這個方法。
  • 具體命令(Concrete Command):實現 Command 接口,負責調用接收者對象的具體操作。LightOnCommandLightOffCommand 分別負責打開和關閉燈光。
  • 接收者(Receiver)Light 類知道如何執行具體操作,如打開和關閉燈光。
  • 調用者(Invoker)RemoteControl 類持有一個命令對象,通過 setCommand() 方法設置當前命令,并通過 pressButton() 方法執行命令。
  • 客戶端代碼(Client Code):客戶端代碼創建具體的接收者、命令和調用者對象,并通過設置和執行命令來控制燈光的開關。

這種設計模式的優勢在于將請求的發送者和接收者解耦,使得系統更靈活,可以在不修改調用者代碼的情況下新增或更改命令。

優缺點

優點
  1. 降低發送者和接收者之間的耦合
    • 發送者只需要知道如何發送命令,而不需要了解接收者的具體實現。
  2. 容易擴展新命令
    • 可以很容易地增加新的具體命令類。
  3. 支持撤銷和重做操作
    • 可以通過保存歷史命令實現撤銷和重做功能。
缺點
  1. 可能會導致過多的具體命令類
    • 如果系統中命令較多,可能會導致類的數量增加。

類圖

+----------------+         +------------------+
|   Command      |-------->|   ConcreteCommand|
+----------------+         +------------------+
| + execute()    |         | + execute()      |
+----------------+         +------------------+
|                |         |
+----------------+         ||+-------------------+--------+----------------+|                   |                 |                |
+---------------+ +-----------------+ +----------------+ +--------------+
|     Receiver  | |  LightOnCommand | |  LightOffCommand| | ...          |
+---------------+ +-----------------+ +----------------+ +--------------+
| + action()    | | + execute()      | | + execute()     | | + execute()   |
+---------------+ +-----------------+ +----------------+ +--------------+

總結

命令模式允許將請求封裝成對象,使得請求的發送者和接收者解耦,并支持撤銷、重做等操作。通過命令模式,可以輕松擴展新的命令,支持排隊、記錄日志等功能,是一種非常有用的設計模式。

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

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

相關文章

編程參考 - Rule of Three and the Rule of Five in C++

C 中的 "三規則 "和 "五規則 "是管理類中資源管理函數(特殊成員函數)的準則。這些規則有助于確保類正確一致地管理動態內存、文件句柄或網絡連接等資源。 The Rule of Three and the Rule of Five in C are guidelines for managing…

【C++題解】1168. 歌唱比賽評分

問題:1168. 歌唱比賽評分 類型:數組找數 題目描述: 四(1) 班要舉行一次歌唱比賽,以選拔更好的苗子參加校的歌唱比賽。評分辦法如下:設 N 個評委,打 N 個分數( 0≤每個分…

Linux C語言基礎 day10

目錄 學習目標: 學習內容: 1.指針指向數組 1.1 指針與數組的關系 1.2 指針與一維數組關系實現 1.2.1 指針與一維數組的關系 1.2.2 指針指向一維整型數組作為函數參數傳遞 課外作業: 學習目標: 一周掌握 C基礎知識 學習內…

卡碼網語言基礎課 | 10. 平均績點

目錄 1、問題描述2、知識點① 字符串格式化輸出② 保留小數 3、代碼 1、問題描述 題目描述:每門課的成績分為A、B、C、D、F五個等級,為了計算平均績點,規定A、B、C、D、F分別代表4分、3分、2分、1分、0分。 輸入描述:有多組測試…

RandomAccessFile詳細總結

RandomAccessFile 是 Java 中一個非常特殊的類,它既可以用來讀取文件,也可以用來寫入文件。與其他 IO 類(如 FileInputStream 和 FileOutputStream)不同,RandomAccessFile 允許您跳轉到文件的任何位置,從那…

【全面介紹Pip換源】

🎥博主:程序員不想YY啊 💫CSDN優質創作者,CSDN實力新星,CSDN博客專家 🤗點贊🎈收藏?再看💫養成習慣 ?希望本文對您有所裨益,如有不足之處,歡迎在評論區提出…

CV11_模型部署pytorch轉ONNX

如果自己的模型中的一些算子,ONNX內部沒有,那么需要自己去實現。 1.1 配置環境 安裝ONNX pip install onnx -i https://pypi.tuna.tsinghua.edu.cn/simple 安裝推理引擎ONNX Runtime pip install onnxruntime -i https://pypi.tuna.tsinghua.edu.cn/si…

基于Java的斗地主游戲案例開發(做牌、洗牌、發牌、看牌

package Game;import java.util.ArrayList; import java.util.Collections;public class PokerGame01 {//牌盒//?3 ?3static ArrayList<String> list new ArrayList<>();//靜態代碼塊//特點&#xff1a;隨著類的加載而在加載的&#xff0c;而且只執行一次。stat…

底軟驅動 | C++內存相關

文章目錄 C內存相關C內存分區C對象的成員函數存放在內存哪里 堆和棧的區別堆和棧的訪問效率“野指針”有了malloc/free為什么還要new/deletealloca內存崩潰C內存泄漏的幾種情況內存對齊柔性數組參考推薦閱讀 C內存相關 本篇介紹了 C 內存相關的知識。 C內存分區 在C中&#…

力扣第八題——字符串轉換整數

題目介紹 請你來實現一個 myAtoi(string s) 函數&#xff0c;使其能將字符串轉換成一個 32 位有符號整數。 函數 myAtoi(string s) 的算法如下&#xff1a; 空格&#xff1a;讀入字符串并丟棄無用的前導空格&#xff08;" "&#xff09;符號&#xff1a;檢查下一個字…

TCP重傳、滑動窗口、流量控制、擁塞控制機制

目錄 1、TCP重傳機制超時重傳快速重傳 2、滑動窗口3、流量控制4、擁塞控制1、慢啟動2、擁塞避免3、擁塞發生 1、TCP重傳機制 TCP 針對數據包丟失的情況&#xff0c;會用重傳機制解決。 超時重傳 就是在發送數據時&#xff0c;設定一個定時器&#xff0c;當超過指定的時間還沒…

Ctrl+C、Ctrl+V、Ctrl+X 和 Ctrl+Z 的起源

注&#xff1a;機翻&#xff0c;未校對。 The Origins of CtrlC, CtrlV, CtrlX, and CtrlZ Explained We use them dozens of times a day: The CtrlZ, CtrlX, CtrlC, and CtrlV shortcuts that trigger Undo, Cut, Copy, and Paste. But where did they come from, and why do…

文件上傳接口

文章目錄 開發前端接口 開發前端接口 首先這個前端的文件上傳組件使用了,前端組件 首先這個接口不是一般的接口,這個接口可以提取出來,之后那里使用了,就直接放到哪里 所以這是一個萬能文件上傳接口 寫完之后選擇 頭像組件 在圖庫中添加組件 寫前端組件之后,寫了前端的組件…

Bootstrap 5 加載效果

Bootstrap 5 加載效果 Bootstrap 5 是一個流行的前端框架,它提供了豐富的組件和工具,用于快速開發響應式和移動優先的網頁。在本文中,我們將探討 Bootstrap 5 中的加載效果,包括如何實現它們以及它們在網頁設計中的作用。 什么是加載效果? 加載效果是在網頁或應用程序中…

k8s集群創建devops項目一直等待狀態,沒有發現host

問題分析&#xff1a; kubesphere在幫我們自動化創建一些智能自動化的額時候難免會發生一些小錯誤&#xff0c;devops-jenkins是一個部署也會生成一個容器組即pod&#xff0c;容器組的容器服務端口是 targetPort&#xff0c;容器組對外暴露的端口是port&#xff0c;拿devops-c…

[深度學習]基于yolov10+streamlit目標檢測演示系統設計

YOLOv10結合Streamlit構建的目標檢測系統&#xff0c;不僅極大地增強了實時目標識別的能力&#xff0c;還通過其直觀的用戶界面實現了對圖片、視頻乃至攝像頭輸入的無縫支持。該系統利用YOLOv10的高效檢測算法&#xff0c;能夠快速準確地識別圖像中的多個對象&#xff0c;并標注…

Billu_b0x靶機

信息收集 使用arp-scan 生成網絡接口地址來查看ip 輸入命令&#xff1a; arp-scan -l 可以查看到我們的目標ip為192.168.187.153 nmap掃描端口開放 輸入命令&#xff1a; nmap -min-rate 10000 -p- 192.168.187.153 可以看到開放2個端口 nmap掃描端口信息 輸入命令&…

配置PYTHONPATH環境變量

配置PYTHONPATH環境變量 前言Win系統臨時配置永久配置 Linux系統臨時配置永久配置 前言 在運行py腳本時不僅需要import官方庫&#xff0c;經常會import自己編寫的腳本&#xff0c;但此時會出現模塊找不到的如下報錯。解決方法是配置PYTHONPATH&#xff0c;下文介紹Win系統和Li…

禹神:一小時快速上手Electron,前端Electron開發教程,筆記。一篇文章入門Electron

一、Electron是什么 簡單的一句話&#xff0c;就是用htmlcssjsnodejs&#xff08;Native Api&#xff09;做兼容多個系統&#xff08;Windows、Linux、Mac&#xff09;的軟件。 官網解釋如下(有點像繞口令)&#xff1a; Electron是一個使用 JavaScript、HTML 和 CSS 構建桌面…

Resources.Load返回null

Resources.Load返回null 在unity中Resources.Load從Assets下的任意Resources目錄下讀取資源&#xff0c;比如從Assets\Resources下讀取Cube&#xff08;預制體&#xff09;&#xff0c;當然也可以讀取其他資源 代碼為 GameObject prefab Resources.Load<GameObject>(…