探討命令模式及其應用

目錄

  • 命令模式
    • 命令模式結構
    • 命令模式適用場景
    • 命令模式優缺點
    • 練手題目
      • 題目描述
      • 輸入描述
      • 輸出描述
      • 題解

命令模式

命令模式是一種行為設計模式, 它可將請求轉換為一個包含與請求相關的所有信息的獨立對象。 該轉換讓你能根據不同的請求將方法參數化、 延遲請求執行或將其放入隊列中, 且能實現可撤銷操作。

命令模式結構

在這里插入圖片描述

  1. 發送者(Sender)——亦稱 “觸發者(Invoker)”——類負責對請求進行初始化,其中必須包含一個成員變量來存儲對于命令對象的引用。發送者觸發命令,而不向接收者直接發送請求。注意,發送者并不負責創建命令對象:它通常會通過構造函數從客戶端處獲得預先生成的命令。
  2. 命令(Command)接口通常僅聲明一個執行命令的方法。
  3. 具體命令 (Concrete Commands)會實現各種類型的請求。具體命令自身并不完成工作,而是會將調用委派給一個業務邏輯對象。但為了簡化代碼,這些類可以進行合并。接收對象執行方法所需的參數可以聲明為具體命令的成員變量。你可以將命令對象設為不可變,僅允許通過構造函數對這些成員變量進行初始化。
  4. 接收者(Receiver)類包含部分業務邏輯。幾乎任何對象都可以作為接收者。絕大部分命令只處理如何將請求傳遞到接收者的細節,接收者自己會完成實際的工作。
  5. 客戶端(Client)會創建并配置具體命令對象。客戶端必須將包括接收者實體在內的所有請求參數傳遞給命令的構造函數。此后,生成的命令就可以與一個或多個發送者相關聯了。

命令模式通用代碼:

//抽象接收者
public abstract class Receiver{public abstract void operation();
}//具體接收者
public class Recevier1 extends Recevier{public void operation(){...}
}//通用命令接口
public interface Command{void execute();
}//具體命令類
public class ConcreteCommand1 implements Command{private Receiver receiver;public ConcreteCommand1(Receiver _receiver){this.receiver = _receiver;}public void execute(){this.receiver.operation();}
}//調用者類
public class Invoker{private Command command;public void setCommand(Command _command){this.command = _command;}public void executeCommand(){this.command.execute();}}//主程序類
public class Client{public static void main(String[] args){//調用者Invoker invoker = new Invoker();//接收者Receiver receiver1 = new Receiver1();//定義一個命令Command command = new ConcreteCommand1(receiver1);invoker.setCommand(command);invoker.executeCommand();}
}

命令模式適用場景

  1. 如果你需要通過操作來參數化對象,可使用命令模式。

    命令模式可將特定的方法調用轉化為獨立對象。 這一改變也帶來了許多有趣的應用: 你可以將命令作為方法的參數進行傳遞、 將命令保存在其他對象中, 或者在運行時切換已連接的命令等。

  2. 如果你想要將操作放入隊列中、操作的執行或者遠程執行操作,可使用命令模式。

    同其他對象一樣,命令也可以實現序列化(序列化的意思是轉化為字符串),從而能方便地寫入文件或數據庫中。一段時間后,該字符串可被恢復成為最初的命令對象。因此,你可以延遲或計劃命令的執行。但其功能遠不止如此!使用同樣的方式,你還可以將命令放入隊列、記錄命令或者通過網絡發送命令。

  3. 如果你想要實現操作回滾功能,可使用命令模式。

在這里插入圖片描述

**識別方法:**命令模式可以通過抽象或接口類型(發送者)中的行為方法來識別, 該類型調用另一個不同的抽象或接口類型 (接收者)實現中的方法,該實現則是在創建時由命令模式的實現封裝。命令類通常僅限于一些特殊行為。

命令模式優缺點

命令模式優點:

  • 單一職責原則。你可以解耦觸發和執行操作的類。
  • 開閉原則。你可以在不修改已有客戶端代碼的情況下在程序中創建新的命令。
  • 你可以實現撤銷和恢復功能。
  • 你可以實現操作的延遲執行。
  • 你可以將一組簡單命令組合成一個復雜命令。

命令模式缺點:

  • 代碼可能會變得更加復雜,因為你在發送者和接收者之間增加了一個全新的層次。

練手題目

題目描述

小明去奶茶店買奶茶,他可以通過在自助點餐機上來點不同的飲品,請你使用命令模式設計一個程序,模擬這個自助點餐系統的功能。

輸入描述

第一行是一個整數 n(1 ≤ n ≤ 100),表示點單的數量。

接下來的 n 行,每行包含一個字符串,表示點餐的飲品名稱。

輸出描述

輸出執行完所有點單后的制作情況,每行輸出一種飲品的制作情況。如果制作完成,輸出 “XXX is ready!”,其中 XXX 表示飲品名稱。

在這里插入圖片描述

題解

解法一:

import java.util.Scanner;// 枚舉類表示飲料類型
enum BeverageType {MILKTEA, COFFEE, COLA
}// 抽象飲料類
abstract class Beverage {abstract void make();
}// 具體飲料類
class MilkTea extends Beverage {@Overridepublic void make() {System.out.println("MilkTea is ready!");}
}class Coffee extends Beverage {@Overridepublic void make() {System.out.println("Coffee is ready!");}
}class Cola extends Beverage {@Overridepublic void make() {System.out.println("Cola is ready!");}
}// 抽象命令類
abstract class Command {protected Beverage beverage;public Command(Beverage _beverage) {this.beverage = _beverage;}abstract void execute();
}// 具體命令類
class MilkTeaCommand extends Command {public MilkTeaCommand() {super(new MilkTea());}@Overridepublic void execute() {beverage.make();}
}class CoffeeCommand extends Command {public CoffeeCommand() {super(new Coffee());}@Overridepublic void execute() {beverage.make();}
}class ColaCommand extends Command {public ColaCommand() {super(new Cola());}@Overridepublic void execute() {beverage.make();}
}// 調用者類
class Invoker {private Command command;public void setCommand(Command _command) {command = _command;}public void action() {command.execute();}
}// 主類
public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);try {Invoker invoker = new Invoker();int n = scanner.nextInt();scanner.nextLine();for (int i = 0; i < n; i++) {String type = scanner.nextLine().trim().toUpperCase();try {switch (BeverageType.valueOf(type)) {case MILKTEA:invoker.setCommand(new MilkTeaCommand());break;case COFFEE:invoker.setCommand(new CoffeeCommand());break;case COLA:invoker.setCommand(new ColaCommand());break;default:System.out.println("請重新輸入:");continue;}invoker.action();} catch (IllegalArgumentException e) {System.out.println("無效的飲料類型");}}} catch (Exception e) {System.out.println("發生錯誤: " + e.getMessage());} finally {scanner.close();}}
}

解法二:

import java.util.Scanner;// 命令接口
interface Command {void execute();
}// 具體命令類 - 點餐命令
class OrderCommand implements Command {private String drinkName;private DrinkMaker receiver;public OrderCommand(String drinkName, DrinkMaker receiver) {this.drinkName = drinkName;this.receiver = receiver;}@Overridepublic void execute() {receiver.makeDrink(drinkName);}
}// 接收者類 - 制作飲品
class DrinkMaker {public void makeDrink(String drinkName) {System.out.println(drinkName + " is ready!");}
}// 調用者類 - 點餐機
class OrderMachine {private Command command;public void setCommand(Command command) {this.command = command;}public void executeOrder() {command.execute();}
}public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);// 創建接收者和命令對象DrinkMaker drinkMaker = new DrinkMaker();// 讀取命令數量int n = scanner.nextInt();scanner.nextLine();while (n-- > 0) {// 讀取命令String drinkName = scanner.next();// 創建命令對象Command command = new OrderCommand(drinkName, drinkMaker);// 執行命令OrderMachine orderMachine = new OrderMachine();orderMachine.setCommand(command);orderMachine.executeOrder();}scanner.close();}
}

解法三:命令模式+工廠模式

import java.util.Scanner;// 命令接口
interface Command {void execute();
}// 具體命令類 - 點餐命令
class OrderCommand implements Command {private String drinkName;private DrinkMaker receiver;public OrderCommand(String drinkName, DrinkMaker receiver) {this.drinkName = drinkName;this.receiver = receiver;}@Overridepublic void execute() {receiver.makeDrink(drinkName);}
}// 接收者類 - 制作飲品
class DrinkMaker {public void makeDrink(String drinkName) {System.out.println(drinkName + " is ready!");}
}// 調用者類 - 點餐機
class OrderMachine {private Command command;public void setCommand(Command command) {this.command = command;}public void executeOrder() {if (command != null) {command.execute();} else {System.out.println("未設置命令.");}}
}// 命令工廠類
class CommandFactory {private DrinkMaker drinkMaker;public CommandFactory(DrinkMaker drinkMaker) {this.drinkMaker = drinkMaker;}public Command createCommand(String drinkName) {return new OrderCommand(drinkName, drinkMaker);}
}// 主類
public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);// 創建接收者和工廠對象DrinkMaker drinkMaker = new DrinkMaker();CommandFactory commandFactory = new CommandFactory(drinkMaker);OrderMachine orderMachine = new OrderMachine();// 讀取命令數量int n = scanner.nextInt();scanner.nextLine();while (n-- > 0) {// 讀取命令String drinkName = scanner.nextLine().trim();if (drinkName.isEmpty()) {System.out.println("無效輸入,請輸入飲品名.");continue;}// 使用工廠創建命令對象Command command = commandFactory.createCommand(drinkName);// 設置命令并執行orderMachine.setCommand(command);orderMachine.executeOrder();}scanner.close();}
}

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

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

相關文章

《亞馬遜搬運亞馬遜產品》配合跟賣采集爬取跟賣店鋪高質量

亞馬遜高質量產品如何搬運&#xff1f;亞馬遜采集亞馬遜。 哈嘍大家好&#xff0c;大家講一下做亞馬遜是發貨、鋪貨這塊的功能。目前這款軟件做跟賣大家都知道&#xff0c;同時也支持做鋪貨。鋪貨可以采集國內的1688、淘寶、京東都可以采&#xff0c;采完之后也可以采速賣通&a…

周周星分享7.3—基于氣象大數據的自動站實況聯合預測

賽題 2024中國高校計算機大賽 — 大數據挑戰賽 經驗分享 大家好&#xff0c;我是掃地僧團隊的隊長&#xff0c;以前參加這樣打榜的比賽比較少&#xff0c;了解的打榜技巧不是太多&#xff0c;所以想從科研的角度給大家一點分享。 這次比賽主要從以下五個步驟進行&#xff1a…

Linux Doxygen快速生成文檔

此前寫過一篇編寫Doxygen格式的注釋以用于生成文檔,點擊以查閱, Doxygen常用語法與字段記錄,但是當時用的windows桌面版的doxygen,最近使用ubuntu編寫代碼想直接使用doxygen生成,故寫下此博客 Doxygen Doxygen是一個用于生成軟件文檔的工具&#xff0c;它可以從代碼中提取注釋…

(四)opengl函數加載和錯誤處理

#include <glad/glad.h>//glad必須在glfw頭文件之前包含 #include <GLFW/glfw3.h> #include <iostream>void frameBufferSizeCallbakc(GLFWwindow* window, int width, int height) {glViewport(0, 0, width, height);std::cout << width << &qu…

PHP多線程爬蟲:高效解析電商網頁內容

如何使用php多線程編寫高效的網頁爬蟲 隨著互聯網的發展和數據的不斷增長&#xff0c;網頁爬蟲成為了一種非常重要的工具。通過網頁爬蟲&#xff0c;我們可以自動地從各種網站上獲取大量的數據&#xff0c;并進行進一步的處理和分析。而PHP作為一種廣泛使用的編程語言&#xf…

Android高級面試_6_性能優化

Android 高級面試-7&#xff1a;網絡相關的三方庫和網絡協議等 1、網絡框架 問題&#xff1a;HttpUrlConnection, HttpClient, Volley 和 OkHttp 的區別&#xff1f; HttpUrlConnection 的基本使用方式如下&#xff1a; URL url new URL("http://www.baidu.com")…

SwanLinkOS首批實現與HarmonyOS NEXT互聯互通,軟通動力子公司鴻湖萬聯助力鴻蒙生態統一互聯

在剛剛落下帷幕的華為開發者大會2024上&#xff0c;伴隨全場景智能操作系統HarmonyOS Next的盛大發布&#xff0c;作為基于OpenHarmony的同根同源系統生態&#xff0c;軟通動力子公司鴻湖萬聯全域智能操作系統SwanLinkOS首批實現與HarmonyOS NEXT互聯互通&#xff0c;率先攻克基…

大模型與機器人精彩碰撞-7月5日晚上八點不見不散!

在瞬息萬變的科技時代&#xff0c;新興人工智能和機器人技術的結合正在引領新一輪的創新浪潮。你是否想成為未來科技的領航者&#xff1f;你是否想了解最前沿的AI與機器人技術&#xff1f;行麥科技重磅推出的“AIGC時代的生存法則”AI系列課&#xff0c;將為你揭開大模型與機器…

創建kset

1、kset介紹 2、相關結構體和api介紹 2.1 struct kset 2.2 kset_create_and_add kset_create_and_addkset_createkset_registerkobject_add_internalkobject_add_internal2.3 kset_unregister kset_unregisterkobject_delkobject_put3、實驗操作 #include<linux/module.…

【leetcode64-69二分查找、70-74棧、75-77堆】

二分查找[64-69] 時間復雜度O(log n)&#xff0c;要想到二分排序 35.搜索插入位置 class Solution:def searchInsert(self, nums: List[int], target: int) -> int:left 0right len(nums)-1while left < right: #左閉右閉mid (leftright)//2if nums[mid] < target…

【算法訓練記錄——Day39】

Day39——動態規劃Ⅱ 1.leetcode_62不同路徑2.leetcode_63不同路徑Ⅱ3.leetcode_343整數拆分4.leetcode_96不同的二叉樹搜索 1.leetcode_62不同路徑 思路&#xff1a;經典的動態規劃問題&#xff1a; dp[i][j]表示到達&#xff08;i&#xff0c;j&#xff09;位置時的不同路徑…

運維鍋總淺析云原生DevOps工具

本文從Tekton與Kubevela、Jenkins、GitLab CI的區別與聯系對常見的云原生DevOps工具進行對比分析&#xff0c;最后給出DevOps工具選型思路。希望對您有所幫助&#xff01; 一、DevOps簡介 DevOps是一種結合了軟件開發&#xff08;Development&#xff09;和IT運維&#xff08…

怎么在windows、linux、mac上安裝pnpm呢?

怎么在windows、linux、mac上安裝pnpm呢&#xff1f; 前言 如果您不使用獨立腳本或 pnpm/exe 來安裝 pnpm&#xff0c;則需要在系統上安裝 Node.js&#xff08;至少 v16.14&#xff09;。 原址&#xff1a;https://pnpm.io/zh/installation 使用獨立腳本安裝 即使沒有安裝…

登錄功能和校驗

基礎版 controller package com.web.management.controller;import com.web.management.pojo.Emp; import com.web.management.pojo.Result; import com.web.management.service.EmpService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.anno…

Ignis 應用: 社交 + 游戲 + 工業4.0,Ignis 構建Web3生態圈

引言 在數字經濟快速發展的今天&#xff0c;Web3技術為我們帶來了前所未有的變革。作為Ardor平臺的主要子鏈&#xff0c;Ignis公鏈在推動Web3生態系統建設中扮演了重要角色。本文將通過介紹Vessel Chain、Mythical Beings和Bridge Champ等應用&#xff0c;探討Ignis公鏈如何通…

GB/T 43566-2023中小學人造草面層足球場地檢測

人造草面層是指以類似天然草的合成纖維經機械編織固定于底布上形成人造草&#xff0c;至現場粘接并與彈性墊層等必要的其他材料組裝成整體的面層。 GB/T 43566-2023中小學人造草面層足球場地檢測項目&#xff1a; 測試項目 測試方法 人造草物理性能 GB/T 20394 人造草有害…

html+css+js文章模板

圖片 源代碼在圖片后面&#xff0c;點贊加關注&#xff0c;謝謝&#x1f604; 源代碼 <!DOCTYPE html> <html lang"zh"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width,…

redis的數據類型對應的使用場景

Redis提供了多種數據類型&#xff0c;每種數據類型都有其特定的適用場景。以下是Redis主要數據類型及其典型應用場景&#xff1a;1. 字符串(String) 應用場景&#xff1a;適用于存儲簡單的鍵值對數據&#xff0c;如用戶基本信息、計數器&#xff08;如網頁訪問次數&…

停車場車牌識別計費系統,用Python如何實現?

關注星標&#xff0c;每天學習Python新技能 前段時間練習過的一個小項目&#xff0c;今天再看看&#xff0c;記錄一下~ 項目結構 說明&#xff1a; datefile文件夾&#xff1a;保存車輛信息表的xlsx文件 file文件夾&#xff1a;保存圖片文件夾。ic_launcher.jpg是窗體的右上角…

周下載量20萬的npm包---store

https://www.npmjs.com/package/store <script setup> import { onMounted } from vue import store from storeonMounted(() > {store.set(user, { name: xutongbao })let user store.get(user)console.log(user) //對象console.log(localStorage.getItem(user)) //…