当前位置: 首页 > news >正文

设计模式-命令模式

命令模式

  • 问题背景
  • 命令模式
    • 基本介绍
    • 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&#xff09;随着现在科技越来越先进&#xff0c;我们在家庭中对物品的开关都不需要亲自走过去来进行了。我们只需要通过手机APP中的按键来远程执行这个命令。 2&#xff09;其实这就是命令模式&…...

软考——下午题部分,例题一,二,三,六

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

关于render: h => h(App)的解释

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

flask实现简易图书管理系统

项目结构 技术选型 flask 做后端, 提供数据和渲染html 暂时没有提供mysql, 后续会更新操作mysql和样式美化的版本 起一个flask服务 flask是python的一个web框架, 下面演示如何提供http接口, 并返回json数据 main.py # flask创建http接口 from flask import Flask, request, jso…...

2021 年全国大学生物联网设计竞赛(华为杯)全国总决赛获奖名单

由全国高等学校计算机教育研究会主办&#xff0c;上海交通大学承办&#xff0c;华为技术有限 公司协办&#xff0c;中国电信天翼物联、中国移动中移物联网、霍尼韦尔 Tridium、CSA 联盟、新大陆、德州仪器 (TI)、百度、机械工业出版社华章公司联合支持的 2021 全国大学生物联网…...

操作系统复习2.3.5-管程

引入管程 PV操作困难&#xff0c;容易书写出错&#xff0c;引入管程&#xff0c;作为一种高级同步机制 组成 局限于管程的共享数据结构说明对该数据结构进行操作的一组过程对局部于管程的共享数据结构设置初始值的语句管程有一个名字 基本特征 局限于管程的数据只能被局限…...

List Set Map Queue Deque 之间的区别是什么?

List Set Map Queue Deque 之间的区别是什么&#xff1f; 1. Java 集合框架有那些接口&#xff1f;2. List Set Map Queue Deque 之间的区别是什么&#xff1f; 1. Java 集合框架有那些接口&#xff1f; List、Set、Map、Queue、Deque 2. List Set Map Queue Deque 之间的区别…...

unity行为决策树实战详解

一、行为决策树的概念 行为决策树是一种用于游戏AI的决策模型&#xff0c;它将游戏AI的行为分解为一系列的决策节点&#xff0c;并通过节点之间的连接关系来描述游戏AI的行为逻辑。在行为决策树中&#xff0c;每个节点都代表一个行为或决策&#xff0c;例如移动、攻击、逃跑等…...

Spring学习记录

目录 bean的单例与多例 设置 工厂模式的三种形态 简单工厂模式 代码&#xff1a; 运行结果&#xff1a; 总结&#xff1a; 工厂模式 代码&#xff1a; 运行结果&#xff1a; 总结&#xff1a; 抽象工厂模式 代码&#xff1a; 运行结果&#xff1a; 总结&#xff1a; …...

模板方法-

定义&#xff1a;又叫模板模式,是指定义一个算法骨架,并允许子类为其中的一个或多个步骤提供实现。 适用场景&#xff1a; 1、一次性实现一个算法不变的部分,并将可变的行为留给子类来实现 2、各子类中公共的行为被提取出来并集中到一个公共的父类中,从而避免代码重复 优点…...

[Kubernetes] - RabbitMQ学习

1.消息队列 消息&#xff1a; 在应用间传送的数据队列&#xff0c;先进先出 1.2. 作用 好处&#xff1a;解耦&#xff0c; 容错&#xff0c;削峰坏处&#xff1a;降低系统可用性&#xff0c;系统复杂度提高&#xff0c;一致性问题&#xff1b; RabbitMQ组成部分&#xff1a…...

swagger页面 doc.html出不来,swagger-ui/index.html能出来

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

IEEE802.3和IEEE802.11的分类(仅为分类)

IEEE802.3标准 IEEE802.3:10兆以太网 ●10Base&#xff0d;5 使用粗同轴电缆&#xff0c;最大网段长度为500m&#xff0c;基带传输方法&#xff1b; ●10Base&#xff0d;2 使用细同轴电缆&#xff0c;最大网段长度为185m&#xff0c;基带传输方法&#xff1b; ●10Base&am…...

c# cad二次开发通过获取excel数据 在CAD绘图,将CAD属性导出到excel

c# cad二次开发通过获取excel数据 在CAD绘图&#xff0c;将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 是一个开源的向量数据库引擎&#xff0c;旨在提供高效的向量存储、检索和分析能力。它被设计用于处理大规模的高维向量数据&#xff0c;常用于机器学习、计算机视觉…...

实体类注解

目录 一、TableField注解 二、TableId注解 三、Table注解 四、TableLogic注解 五、Getter与Setter注解 六、EqualsAndHashCode注解 七、Accessors注解 一、TableField注解 Data NoArgsConstructor //空参构造方法 AllArgsConstructor //全参构造方法 TableName("t…...

常见数据结构种类

常见数据结构种类 数据存储的常用结构有&#xff1a;栈、队列、数组、链表和红黑树 a.队列&#xff08;queue&#xff09; – 先进先出&#xff0c;后进后出。 – 场景&#xff1a;各种排队。叫号系统。 – 有很多集合可以实现队列。 b.栈&#xff08;stack&#xff09; – …...

linux高级---k8s中的五种控制器

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

记一次udp服务性能优化经历

目录 概述磁盘io网络io减少重复计算减少内存复制减少互斥锁 概述 手上有个go项目&#xff0c;接收udp信息&#xff08;主要是syslog和snmp trap&#xff09;并查询设备信息&#xff0c;将信息结构化&#xff08;设备ip名称&#xff0c;匹配了什么规则之类的&#xff09;后发送…...

uniapp和VueI18n多语言H5项目语言国际化功能搭建流程

uniapp多语言项目国家化功能搭建流程 说明&#xff1a;uniapp多语言项目功能搭建分为应用部分和框架部分。 应用部分&#xff0c;即开发者自己的代码里涉及的界面部分的语言翻译。框架部分&#xff0c;即uni-app内置组件和API涉及界面的部分的语言翻译。 功能的搭建是需要un…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

大话软工笔记—需求分析概述

需求分析&#xff0c;就是要对需求调研收集到的资料信息逐个地进行拆分、研究&#xff0c;从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要&#xff0c;后续设计的依据主要来自于需求分析的成果&#xff0c;包括: 项目的目的…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

Java 8 Stream API 入门到实践详解

一、告别 for 循环&#xff01; 传统痛点&#xff1a; Java 8 之前&#xff0c;集合操作离不开冗长的 for 循环和匿名类。例如&#xff0c;过滤列表中的偶数&#xff1a; List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

华为OD机试-食堂供餐-二分法

import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

Android第十三次面试总结(四大 组件基础)

Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成&#xff0c;用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机&#xff1a; ​onCreate()​​ ​调用时机​&#xff1a;Activity 首次创建时调用。​…...