毅四捕Go设计模式笔记——命令模式

命令模式(Command Pattern)

为了解决什么问题?

命令模式的目的是将请求发起者和请求执行者解耦,使得请求的发起者不需要知道具体的执行者是谁,也不需要知道执行的具体过程,只需要发送请求即可。

通过使用命令对象来封装请求,可以参数化和传递可调用的动作。同时,支持可撤销操作和队列请求等功能。

怎么用代码实现?

下面让我们通过一个餐厅下单的例子来看看怎么实现命令模式。例子里包含三个角色:

  • 顾客
  • 服务员
  • 厨师
    服务员在收到顾客的点餐请求后,然后将请求封装成命令,并交给厨师准备食物。

首先,定义好作为命令执行者的厨师,这里的厨师会制作汉堡包和沙拉。

/*** 厨师接收点菜的命令并开始烹饪*/
public class Chef {public void makeBurger() {System.out.println("Chef is making a burger");}public void makeSalad() {System.out.println("Chef is making a salad");}
}

然后,定义抽象下单命令,以及具体的汉堡包和沙拉的下单命令。

public interface OrderCommand {void execute();
}/*** 烹饪汉堡包的命令*/
public class BurgerOrderCommand implements OrderCommand {@Overridepublic void execute(Chef chef) {chef.makeBurger();}
}/*** 准备沙拉的命令*/
public class SaladOrderCommand implements OrderCommand {@Overridepublic void execute(Chef chef) {chef.makeSalad();}
}

接着,定义服务员角色。

/*** 服务员是命令的调用者*/
public class Waiter {private Chef chef;private OrderCommand orderCommand;public Waiter(Chef chef) {this.chef = chef;}public void sendOrderCommandToKitchen(OrderCommand orderCommand) {this.orderCommand = orderCommand;System.out.println("Waiter sending order to kitchen...");orderCommand.execute(chef);}
}

最后,顾客通过服务员下单,让厨师做出想吃的菜品。

/*** 餐厅顾客类*/
public class RestaurantClient {public static void main(String[] args) {Chef chef = new Chef(); // 接收方Waiter waiter = new Waiter(chef); // 调用方OrderCommand burgerOrder = new BurgerOrderCommand(); // 顾客想吃汉堡waiter.sendOrderCommandToKitchen(burgerOrder); // 服务员收到顾客订单后,将订单发送至厨房OrderCommand saladOrder = new SaladOrderCommand(); // 顾客改主意,想吃沙拉waiter.sendOrderCommandToKitchen(saladOrder); // 服务员收到顾客订单后,将订单发送至厨房}
}

为什么可以解决这个问题?

命令模式通过将具体的请求封装成对象,使得发起请求的操作和接收请求的对象之间不直接发生依赖关系,从而实现请求发起者和请求执行者的解耦。

因为命令对象把请求封装成了对象,这使得你可以用不同的请求、队列或者日志来参数化其他对象,也可以支持撤销操作。

命令模式适用于哪些场景?

参数化对象:需要将请求参数化并传递给调用者时,可以使用命令模式。

操作排队:需要将请求排队执行,例如任务队列、线程池等。

支持撤销操作:需要提供撤销和恢复请求功能的场景。

支持宏命令:可以使用命令模式组合多个命令,实现宏命令的功能。

命令模式在开源代码中比较场景,下面是典型的案例:

Swing中的Action:Java Swing库中,javax.swing.Action接口代表了一个抽象的用户界面动作,它本身就是命令模式的一种实现。

Guava的事件总线:Guava库中的事件总线(EventBus)可以结合命令模式使用,发布者发布命令事件,而订阅者则执行相关的命令。

命令模式把发送命令的责任和执行命令的责任分开,确保了系统设计的灵活性和扩展性。此外,它还简化了其他对象的逻辑,因为它们不需要知道实际的执行逻辑。这一模式特别适用于实现撤销(redo)/恢复(undo)操作、事务系统等需要定义、存储、传递和执行请求的场合。

———————————这是分割线———————————

欢迎添加博主vx深入交流:
博主微信

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/830486.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何轻松在D盘新建文件夹?意外丢失的文件夹怎么找回

对于很多刚接触电脑的朋友来说,如何正确地新建文件夹并将其放置在特定盘符(如D盘)可能是一个不小的挑战。同时,如果新建的文件夹突然消失,而我们又确信自己没有删除它,那么该如何找回呢?本文将为…

ORB-SLAM2算法单目流程

ORB-SLAM系列算法框架比较复杂,下面来梳理一下单目算法的流程。 一:单目初始化 单目初始化也就是单目的地图初始化。流程如下: * Step 1:(未创建)得到用于初始化的第一帧,初始化需要两帧 * …

直播间怎么提高流量?巨量千川官方真实投流助力获客轻松翻倍

随着互联网的快速发展,直播已经成为了一种极具吸引力和互动性的娱乐和营销方式。然而,如何提高直播间的流量,(直播间流量:kxs7667)吸引更多观众成为了每个直播主都关注的重要问题。与此同时,巨量千川官方真实投流作为一…

如何在WordPress中设置网站的SEO标题和描述

在WordPress中,想要让你的网站在搜索引擎结果中脱颖而出,设置优秀的SEO标题和描述至关重要。这不仅可以帮助搜索引擎更好地理解你的网站内容,还可以吸引更多的点击率和流量。而选择一款合适的SEO插件是实现这一目标的关键之一。让我们来看看两…

pgvector扩展在IvorySQL Oracle兼容模式下的应用实践

向量数据库是生成式人工智能(GenAI)的关键组成部分。作为PostgreSQL的重要扩展,pgvector支持高达16000维的向量计算能力,使得PostgreSQL能够直接转化为高效的向量数据库。 IvorySQL基于PostgreSQL开发,因此它同样支持添加pgvector扩展。在Ora…

部署YUM仓库及NFS共享服务

YUM yum仓库常用类型: 本地源仓库:baserulfile:// 在线源仓库:baserulhttp:// ftp源仓库:baseru:ftp:// 实验: 首先安装软件 [rootlocalhost yum.repos.d]# cd /mnt/Packages/ [rootloca…

5G图标显示分析二

1、需求 客户需求&#xff0c;5G手机在部分场景需要显示成5G。当带宽大于50M时&#xff0c;显示5G。 2、Android对应接口 2.1、MTK 平台 04-24 09:55:15.854 1917 2026 D RILJ : [UNSL]< UNSOL_PHYSICAL_CHANNEL_CONFIG [{mConnectionStatusPrimaryServing,mCellBand…

基于FPGA的数字信号处理(3)--什么是浮点数?

科学计数法 你可能不了解「浮点数」&#xff0c;但你一定了解「科学记数法」。 10进制科学记数法把一个数表示成a与10的n次幂相乘的形式&#xff08;1≤|a|<10&#xff0c;a不为分数形式&#xff0c;n为整数&#xff09;&#xff0c;例如&#xff1a; 19970000000000 1.9…

2024-04学习笔记

1.sql优化-子查询改为外连接 1.改之前 改之前是这样&#xff0c;那针对查出来的每一条数据&#xff0c;都要执行一次箭头所指的函数 执行的sql很慢 2.改之后 改之后是这样&#xff0c;整体做外连接&#xff0c;不用每一条都再执行一次查询 执行时间缩短了好几倍 2.Mybatis中…

Mysql基础(四)DML之insert语句

一 insert 语句 强调&#xff1a; 本文介绍的内容很基础,仅做记录用,参考价值较少 ① 总述 目的&#xff1a; 增加rows记录1、完整格式insert [into] 表名[字段名1[, 字段名2]] value[s](值1, 值2);备注&#xff1a;指定部分字段添加,没有被指定的字段要么会自动增长,要…

【Keil】预处理指令#ifndef、#define 和 #endif

当时就是因为两个.h文件的预处理指令内容相同&#xff0c;导致其中一个.h文件的声明一直无效&#xff01;&#xff01; 在 C 或 C 编程中&#xff0c;您看到的这两行代码是一种常见的头文件保护机制&#xff0c;用于防止头文件被多重包含&#xff08;include multiple times&a…

MySQL中SELECT语句的执行过程

2.1.1. 一条SELECT语句的执行过程 MySQL 的架构共分为两层&#xff1a;Server 层和存储引擎层 Server层负责建立连接、分析和执行SQL存储引擎层负责数据的存储和提取&#xff0c;支持 InnoDB、MyISAM、Memory 等多个存储引擎&#xff0c;MySQL5.5以后默认使用InnoDB&#xff0…

Nacos、OpenFeign、网关 笔记

一、远程调用 1.1配置RestTemplate配置类 package com.hmall.cart.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate;Configuration public c…

【06016传感器原理与应用】第3章 力学量传感器 期末复习自考复习

第3章 力学量传感器 定义&#xff1a;将力/压力等力学量信号变成电信号的装置 称为力学量传感器。 力学传感器的分类&#xff1a; 应用普遍的&#xff1a;电阻式、压电式、电容式、电感式、谐振式、变磁阻式、光纤式等等。传统的如弹簧&#xff1a;成本低、不需电源&#xff…

Docker-compose的介绍与用法

Docker-compose Docker Compose 是一个开源的容器编排工具&#xff0c;由 Docker 官方开发。它允许开发者定义一个或多个 Docker 容器作为单个服务&#xff0c;并将这些服务组合成一个项目。这些定义被保存在一个 YAML 文件中&#xff0c;称为 docker-compose.yml。 使用 Dock…

C#命名空间常用函数

在C#中&#xff0c;不同命名空间下有各种常用函数&#xff0c;下面列举一些常见的函数及其对应的命名空间&#xff1a; System命名空间&#xff1a; Console.WriteLine()&#xff1a;用于向控制台输出信息。Convert.ToInt32()&#xff1a;用于将其他数据类型转换为整数类型。 S…

uniapp+axios请求的封装

uniappaxios请求的封装 因在用vue3.0时会导致无法引有buildFullPath和settle两个库。所简单处理这两个方法 // utils/request.ts文件代码如下 /***uniappaxios请求的封装 **/import axios from axios import $config from "/config/config" import {getToken,remo…

个人图床解决方案(PicGo+对象存储, 几乎免费)

个人图床解决方案(PicGo对象存储) 原先我的解决方案是github做图床,套一层Cloudflare的cdn来加速国内访问, 但国内访问仍然过慢, 特别是一些图很多的文章, 加载非常慢. 所以我想着改善一下, 在对比了一些解决方案之后, 我选择了PicGo缤纷云搭建主图床, 部分图片放在 去不图床,…

php扩展

查看扩展: print_r(get_loaded_extensions());判断扩展: if (!extension_loaded(gd)) {if (!dl

在STM32上实现嵌入式人工智能应用

引言 随着微控制器的计算能力不断增强&#xff0c;人工智能&#xff08;AI&#xff09;开始在嵌入式系统中扮演越来越重要的角色。STM32微控制器由于其高性能和低功耗的特性&#xff0c;非常适合部署轻量级AI模型。 本文将探讨如何在STM32平台上实现深度学习应用&#xff0c;…