设计模式-命令模式
命令模式
- 问题背景
- 命令模式
- 基本介绍
- UML类图
- 解决方案
- UML类图
- 代码示例
问题背景
1)随着现在科技越来越先进,我们在家庭中对物品的开关都不需要亲自走过去来进行了。我们只需要通过手机APP中的按键来远程执行这个命令。
2)其实这就是命令模式,使用者完全不需要懂这个命令如何执行,谁来执行,使用者只需要发送命令即可。
3)命令模式可将“动作的请求者”从“动作的执行者对象中解耦出来
命令模式
基本介绍
1)命令模式(Command Pattern):在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道彼请求的操作是哪个
我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计
2)命名模式使得请求发送者与请求接收者消除彼此之间的耦合,让对象之间的调用关系更加灵活,实现解耦。
3)在命令模式中,会将一个请求封装为一个对象,以便使用不同参数来表示不同的请求(即命名),同时命令模式也支持可撤销的操作。
4)通俗易懂的理解,将军发布命令,士兵去执行。其中有几个角色,将军(命令发布者)、士兵 (命令的具体执行者) 、命令(连接将军和士兵)。
Invoker是调用者 (将军),Receiver是被调用者 (士兵),MyCommand是命令,实现了Command接口,持有接收对象
5)命令的发送者完全不需知道谁来执行,只需要发送
UML类图
1)Invoker是调用者角色
2)Command是命令调用者,需要执行所有命令都在这里,可以是接口或者抽象类
3)Receiver是接收者,具体执行命令的角色
4)ConcreteCommand将一个接收者对象与一个动作绑定,调用接收者相应的操作
5)不理解可结合实际问题解决得UML类图来理解
解决方案
UML类图
1)原始物品LightReceiver有开关方法
2)继承Command接口创建等得开关命令,开灯命令撤回方法就是关灯,关灯方法撤回方法就是开灯
3)创建一个RemoteController来保存这些命令,调用得时候直接调用RemoteController类即可
4)NoCommand是一个空命令,可以简化我们的判空操作
5)RemoteController类中有两个属性,map用来保存命令,stack用来记录执行的命令
代码示例
/*** 灯* * @author wenqiang* @date 2023/6/1*/
public class LightReceiver {public void on() {System.out.println("开灯");}public void off() {System.out.println("关灯");}
}
/*** 命令接口* * @author wenqiang* @date 2023/6/1*/
public interface Command {/*** 执行命令*/void execute();/*** 撤回命令*/void undo();
}
/*** 开灯命令** @author wenqiang* @date 2023/6/1*/
public class LightOnCommand implements Command {private LightReceiver lightReceiver = new LightReceiver();@Overridepublic void execute() {lightReceiver.on();}@Overridepublic void undo() {lightReceiver.off();}
}
/*** 关灯命令** @author wenqiang* @date 2023/6/1*/
public class LightOffCommand implements Command {private LightReceiver lightReceiver = new LightReceiver();@Overridepublic void execute() {lightReceiver.off();}@Overridepublic void undo() {lightReceiver.on();}
}
/*** 空命令** @author wenqiang* @date 2023/6/1*/
public class NoCommand implements Command {@Overridepublic void execute() {System.out.println("空命令");}@Overridepublic void undo() {System.out.println("空命令");}
}
/*** 控制界面** @author wenqiang* @date 2023/6/1*/
public class RemoteController {/*** 用来保存命令的设置信息*/private Map<String, Command> map = new HashMap<>(8);/*** 用来保存执行的命令 【使用栈】 【用于命令撤回】*/private Stack<Command> stack = new Stack<>();/*** 设置命令** @param name* @param command*/public void setCommond(String name, Command command) {map.put(name, command);}/*** 开** @param name*/public void on(String name) {Command command = map.getOrDefault(name, new NoCommand());command.execute();stack.push(command);}/*** 关** @param name*/public void off(String name) {Command command = map.getOrDefault(name, new NoCommand());command.execute();stack.push(command);}/*** 撤回**/public void undo() {if (stack.isEmpty()) {new NoCommand().undo();return;}Command pop = stack.pop();pop.undo();}
}
我们来设置命令并使用他们
public class Client {public static void main(String[] args) {// 创建一个控制界面RemoteController remoteController = new RemoteController();// 设置命令remoteController.setCommond("灯-开", new LightOnCommand());remoteController.setCommond("灯-关", new LightOffCommand());// 执行命令remoteController.on("灯-开");// 回撤命令remoteController.undo();remoteController.undo();}
}
执行结果
我们来增加一种设备,加入到控制界面
/*** 电视* * @author wenqiang* @date 2023/6/1*/
public class TelevisionReceiver {public void on() {System.out.println("打开电视");}public void off() {System.out.println("关闭电视");}
}
/*** 打开电视命令** @author wenqiang* @date 2023/6/1*/
public class TelevisionOnCommand implements Command {private TelevisionReceiver televisionReceiver = new TelevisionReceiver();@Overridepublic void execute() {televisionReceiver.on();}@Overridepublic void undo() {televisionReceiver.off();}
}
/*** 关闭电视命令** @author wenqiang* @date 2023/6/1*/
public class TelevisionOffCommand implements Command {private TelevisionReceiver televisionReceiver = new TelevisionReceiver();@Overridepublic void execute() {televisionReceiver.off();}@Overridepublic void undo() {televisionReceiver.on();}
}
将新设备的命令增加到控制界面
public class Client {public static void main(String[] args) {// 创建一个控制界面RemoteController remoteController = new RemoteController();// 设置命令remoteController.setCommond("灯-开", new LightOnCommand());remoteController.setCommond("灯-关", new LightOffCommand());remoteController.setCommond("电视-开", new TelevisionOnCommand());remoteController.setCommond("电视-关", new TelevisionOffCommand());// 执行命令remoteController.on("灯-开");remoteController.on("电视-开");remoteController.on("电视-关");// 回撤命令remoteController.undo();remoteController.undo();}
}
执行结果
相关文章:

设计模式-命令模式
命令模式 问题背景命令模式基本介绍UML类图 解决方案UML类图代码示例 问题背景 1)随着现在科技越来越先进,我们在家庭中对物品的开关都不需要亲自走过去来进行了。我们只需要通过手机APP中的按键来远程执行这个命令。 2)其实这就是命令模式&…...

软考——下午题部分,例题一,二,三,六
例题一 11年上半年 病人,护理人员,医生 D 生命体征范围文件 日志文件 病历文件 治疗意见文件 14年上 E1 巴士司机,2 机械师,3 会计,4 主管,5 库存管理系统 D 巴士列表文件 维修记录文件 部件清单 人事档案 14年下 1 客户 2 供应商 D 销售订单表 库存…...

关于render: h => h(App)的解释
当我们第一次安装完脚手架,打开 的时候,我相信,一定有小伙伴和我一样,看到main.js里面的render: h > h(App),感觉懵懵的。 因为,在刚开始接触vue的时候,我们这里是这样写的: 而使用了脚手…...

flask实现简易图书管理系统
项目结构 技术选型 flask 做后端, 提供数据和渲染html 暂时没有提供mysql, 后续会更新操作mysql和样式美化的版本 起一个flask服务 flask是python的一个web框架, 下面演示如何提供http接口, 并返回json数据 main.py # flask创建http接口 from flask import Flask, request, jso…...
2021 年全国大学生物联网设计竞赛(华为杯)全国总决赛获奖名单
由全国高等学校计算机教育研究会主办,上海交通大学承办,华为技术有限 公司协办,中国电信天翼物联、中国移动中移物联网、霍尼韦尔 Tridium、CSA 联盟、新大陆、德州仪器 (TI)、百度、机械工业出版社华章公司联合支持的 2021 全国大学生物联网…...

操作系统复习2.3.5-管程
引入管程 PV操作困难,容易书写出错,引入管程,作为一种高级同步机制 组成 局限于管程的共享数据结构说明对该数据结构进行操作的一组过程对局部于管程的共享数据结构设置初始值的语句管程有一个名字 基本特征 局限于管程的数据只能被局限…...
List Set Map Queue Deque 之间的区别是什么?
List Set Map Queue Deque 之间的区别是什么? 1. Java 集合框架有那些接口?2. List Set Map Queue Deque 之间的区别是什么? 1. Java 集合框架有那些接口? List、Set、Map、Queue、Deque 2. List Set Map Queue Deque 之间的区别…...
unity行为决策树实战详解
一、行为决策树的概念 行为决策树是一种用于游戏AI的决策模型,它将游戏AI的行为分解为一系列的决策节点,并通过节点之间的连接关系来描述游戏AI的行为逻辑。在行为决策树中,每个节点都代表一个行为或决策,例如移动、攻击、逃跑等…...

Spring学习记录
目录 bean的单例与多例 设置 工厂模式的三种形态 简单工厂模式 代码: 运行结果: 总结: 工厂模式 代码: 运行结果: 总结: 抽象工厂模式 代码: 运行结果: 总结: …...
模板方法-
定义:又叫模板模式,是指定义一个算法骨架,并允许子类为其中的一个或多个步骤提供实现。 适用场景: 1、一次性实现一个算法不变的部分,并将可变的行为留给子类来实现 2、各子类中公共的行为被提取出来并集中到一个公共的父类中,从而避免代码重复 优点…...

[Kubernetes] - RabbitMQ学习
1.消息队列 消息: 在应用间传送的数据队列,先进先出 1.2. 作用 好处:解耦, 容错,削峰坏处:降低系统可用性,系统复杂度提高,一致性问题; RabbitMQ组成部分:…...

swagger页面 doc.html出不来,swagger-ui/index.html能出来
swagger页面 doc.html出不来,swagger-ui/index.html能出来。前前后后折腾了很久,jar包冲突,jar包版本,添加路径啥的都弄了,就是出不来。 后来全局搜索“doc.html”页面发现能出来的项目能搜到这个页面: 定…...

IEEE802.3和IEEE802.11的分类(仅为分类)
IEEE802.3标准 IEEE802.3:10兆以太网 ●10Base-5 使用粗同轴电缆,最大网段长度为500m,基带传输方法; ●10Base-2 使用细同轴电缆,最大网段长度为185m,基带传输方法; ●10Base&am…...
c# cad二次开发通过获取excel数据 在CAD绘图,将CAD属性导出到excel
c# cad二次开发通过获取excel数据 在CAD绘图,将CAD属性导出到excel using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Runtime; using System; using System.Collections.Generic; using System.Linq; us…...
LLM之高性能向量检索库
LLM向量数据库 高性能向量检索库milvus简介安装调用 faiss简介安装调用 高性能向量检索库 milvus 简介 Milvus 是一个开源的向量数据库引擎,旨在提供高效的向量存储、检索和分析能力。它被设计用于处理大规模的高维向量数据,常用于机器学习、计算机视觉…...
实体类注解
目录 一、TableField注解 二、TableId注解 三、Table注解 四、TableLogic注解 五、Getter与Setter注解 六、EqualsAndHashCode注解 七、Accessors注解 一、TableField注解 Data NoArgsConstructor //空参构造方法 AllArgsConstructor //全参构造方法 TableName("t…...
常见数据结构种类
常见数据结构种类 数据存储的常用结构有:栈、队列、数组、链表和红黑树 a.队列(queue) – 先进先出,后进后出。 – 场景:各种排队。叫号系统。 – 有很多集合可以实现队列。 b.栈(stack) – …...

linux高级---k8s中的五种控制器
文章目录 一、k8s的控制器类型二、pod与控制器之间的关系三、状态与无状态化对特点四、Deployment1、Deployment的资源清单文件2、在配置清单中调用deployment控制器3、镜像更新4、金丝雀发布5、删除Deployment 五、Statefulset六、DaemonSet1、daemonset的资源清单文件2、在配…...

记一次udp服务性能优化经历
目录 概述磁盘io网络io减少重复计算减少内存复制减少互斥锁 概述 手上有个go项目,接收udp信息(主要是syslog和snmp trap)并查询设备信息,将信息结构化(设备ip名称,匹配了什么规则之类的)后发送…...
uniapp和VueI18n多语言H5项目语言国际化功能搭建流程
uniapp多语言项目国家化功能搭建流程 说明:uniapp多语言项目功能搭建分为应用部分和框架部分。 应用部分,即开发者自己的代码里涉及的界面部分的语言翻译。框架部分,即uni-app内置组件和API涉及界面的部分的语言翻译。 功能的搭建是需要un…...

idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...

【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...