研磨设计模式day12命令模式
目录
定义
几个参数
场景描述
代码示例
参数化设置
命令模式的优点
本质
何时选用
定义

几个参数
Command:定义命令的接口。
ConcreteCommand:命令接口的实现对象。但不是真正实现,是通过接收者的功能来完成命令要执行的操作
Receiver:接收者。真正执行命令的对象。任何类都可能成为一个接收者,只要它能够实现命令要求实现的相应功能
Invoker:要求命令对象执行请求,通常持有命令对象。
Client:创建具体的命令对象,并且设置命令对象的接收者。
场景描述
电脑开机:
机箱上的按钮就相当于是命令对象
机箱相当于是Invoker:要求机箱上的按钮执行哪些动作
主板相当于接收者对象:真正执行命令的对象
命令对象持有接收者对象就相当于按钮有一条线连接着主板,当按钮被按下就通过连接线把命令发出去。
代码示例
定义主板
package day12命令模式;/*** 主板的接口*/
public interface ZhuBanApi {/*** 定义一个功能:开机*/public void open();
}
定义实现,定义两个一个是技嘉主板,一个是微星主板,现在将实现写为一样
不同的主板对同一个命令的操作可以是不同的
技嘉主板
package day12命令模式.Impl;import day12命令模式.ZhuBanApi;public class JiJiaZhuBanImpl implements ZhuBanApi {@Overridepublic void open() {System.out.println("技嘉主板正在开机,请等候");System.out.println("接通电源......");System.out.println("设备检查......");System.out.println("装载系统......");System.out.println("机器正常运转......");System.out.println("机器已经正常打开,请操作");}
}
微星主板
package day12命令模式.Impl;import day12命令模式.ZhuBanApi;public class WeiXingZhuBanImpl implements ZhuBanApi {@Overridepublic void open() {System.out.println("微星主板正在开机,请等候");System.out.println("接通电源......");System.out.println("设备检查......");System.out.println("装载系统......");System.out.println("机器正常运转......");System.out.println("机器已经正常打开,请操作");}
}
定义命令接口:里面只有一个方法就是执行
package day12命令模式;/*** 命令接口,声明执行的操作*/
public interface Command {/*** 执行命令对应的操作*/public void execute();
}
命令实现:我们按下的是按钮,但是按钮本身不知道怎么去启动电脑,只有主板知道,所以我们要持有真正实现命令的接收者--主板对象
package day12命令模式.Impl;import day12命令模式.Command;
import day12命令模式.ZhuBanApi;/*** 开机命令接口的实现*/
public class CommandImpl implements Command {/*** 持有真正实现命令的接收者--主板对象*/private ZhuBanApi zhuBanApi = null;/*** 构造方法,传入主板对象* @param zhuBanApi*/public CommandImpl(ZhuBanApi zhuBanApi){this.zhuBanApi = zhuBanApi;}/*** 实现开机*/@Overridepublic void execute() {this.zhuBanApi.open();}
}
提供机箱,按钮是放置在机箱上的。机箱对象,本身有按钮,持有按钮对应的命令对象也就是Command
package day12命令模式;/*** 机箱对象,本身有按钮,持有按钮对应的命令对象*/
public class Box {/*** 开机命令对象*/private Command openCommand;/*** 设置开机命令对象* @param openCommand 开机命令对象*/public void setOpenCommand(Command openCommand) {this.openCommand = openCommand;}/*** 提供给客户使用,接收并相应用户请求,相当于那妞被按下触发的方法*/public void openButton(){openCommand.execute();}
}
客户使用按钮,把与主板连接好的按钮对象放置在机箱上。
package day12命令模式;import day12命令模式.Impl.CommandImpl;
import day12命令模式.Impl.WeiXingZhuBanImpl;public class Client {public static void main(String[] args) {// 1.创建接收者WeiXingZhuBanImpl zhuban = new WeiXingZhuBanImpl();// 2.设置接收者与命令对象的关系 (按钮要进行开机,使用哪个主板)CommandImpl command = new CommandImpl(zhuban);// 3.创建Invoker,用Invoker来执行命令Box box = new Box();// 4.将2中绑定好关系的命令对象设置到Invoker中,让Invoker持有box.setOpenCommand(command);// 5.调用Invoker中的方法,触发要求执行命令// Box定义了方法,,用持有命令对象接口里面的方法,接口的实现中持有真正实现命令的接收者ZhuBanApi,// ZhuBanApi他去调用真正的开机方法,而这个接口有多个实现类,到底调用哪一个呢?// 因为在创建接收者时已经把微星这个接收者与命令对象绑定起来了,所以用的就是微星的实现类box.openButton();}
}

解析:先new一个主板,主板要跟按钮连接成为一个具体的开机命令,我又new一个机箱,把这个升级过的按钮(带有功能)装到这个机箱上,机箱最后调用这个按钮。
1.会发现命令模式的关键之处就是把请求封装成了对象,也就是命令对象,并定义了统一的执行操作的接口。
2.在命令模式中会有一个组装者,他来维护虚实现与真实实现之间的关系
参数化设置
可以用不同的命令对象,去参数化配置客户的请求

定义主板接口,现在增加一个重启的按钮,因此主板加一个方法来实现重启功能
package day12命令模式;/*** 主板的接口*/
public interface ZhuBanApi {/*** 定义一个功能:开机*/public void open();/*** 定义重启功能*/public void reset();
}
实现类也要改一下
技嘉的
package day12命令模式.Impl;import day12命令模式.ZhuBanApi;/*** 主板的实现*/
public class JiJiaZhuBanImpl implements ZhuBanApi {@Overridepublic void open() {System.out.println("技嘉主板正在开机,请等候");System.out.println("接通电源......");System.out.println("设备检查......");System.out.println("装载系统......");System.out.println("机器正常运转......");System.out.println("机器已经正常打开,请操作");}@Overridepublic void reset() {System.out.println("技嘉主板现在正在重新启动机器,请等候");System.out.println("机器已经正常打开,请操作");}
}
微星的
package day12命令模式.Impl;import day12命令模式.ZhuBanApi;/*** 主板的实现*/
public class WeiXingZhuBanImpl implements ZhuBanApi {@Overridepublic void open() {System.out.println("微星主板正在开机,请等候");System.out.println("接通电源......");System.out.println("设备检查......");System.out.println("装载系统......");System.out.println("机器正常运转......");System.out.println("机器已经正常打开,请操作");}@Overridepublic void reset() {System.out.println("微星主板现在正在重新启动机器,请等候");System.out.println("机器已经正常打开,请操作");}
}
接下来定义命令和按钮,接口不变,添加一个重启命令的实现resetCommandImpl
package day12命令模式.Impl;import day12命令模式.Command;
import day12命令模式.ZhuBanApi;public class ResetCommandImpl implements Command {/*** 持有主板,也就是接收者对象*/private ZhuBanApi zhuBanApi;/*** 构造函数传入* @param zhuBanApi*/public ResetCommandImpl(ZhuBanApi zhuBanApi){this.zhuBanApi = zhuBanApi;}@Overridepublic void execute() {this.zhuBanApi.reset();}
}
Box改造一下,这里增加一个重启命令对象
package day12命令模式;/*** 机箱对象,本身有按钮,持有按钮对应的命令对象*/
public class Box {/*** 开机命令对象*/private Command openCommand;/*** 重启命令对象*/private Command resetCommand;public void setResetCommand(Command resetCommand) {this.resetCommand = resetCommand;}/*** 设置开机命令对象* @param openCommand 开机命令对象*/public void setOpenCommand(Command openCommand) {this.openCommand = openCommand;}/*** 提供给客户使用,接收并相应用户请求,相当于按钮被按下触发的方法*/public void openButton(){openCommand.execute();}/*** 重启按钮*/public void resetButton(){resetCommand.execute();}
}
Client
package day12命令模式;import day12命令模式.Impl.OpenCommandImpl;
import day12命令模式.Impl.ResetCommandImpl;
import day12命令模式.Impl.WeiXingZhuBanImpl;public class Client {public static void main(String[] args) {WeiXingZhuBanImpl zhuban = new WeiXingZhuBanImpl();OpenCommandImpl openCommand = new OpenCommandImpl(zhuban);ResetCommandImpl resetCommand = new ResetCommandImpl(zhuban);Box box = new Box();box.setOpenCommand(openCommand);box.setResetCommand(resetCommand);System.out.println("正确配置");System.out.println(">>>按下开机按钮:>>>");box.openButton();System.out.println(">>>按下重启按钮:>>>");box.resetButton();}
}

命令模式的优点

本质
命令模式的本质:封装请求
何时选用

相关文章:
研磨设计模式day12命令模式
目录 定义 几个参数 场景描述 代码示例 参数化设置 命令模式的优点 本质 何时选用 定义 几个参数 Command:定义命令的接口。 ConcreteCommand:命令接口的实现对象。但不是真正实现,是通过接收者的功能来完成命令要执行的操作 Receiver&#x…...
设计模式 06 适配器模式
适配器模式(Adapter Pattern)属于结构型模式 概述 结构型模式关注如何将现有的类或对象组织在一起形成更加强大的结构。 在生活中,我们经常遇到这样的一个问题:轻薄笔记本通常只有 type-c 或者 usb-a 接口,没有网口。…...
UE4/5Niagara粒子特效之Niagara_Particles官方案例:3.3->4.3
目录 3.3 Visibility Tag 左边的发射器: 发射器更新 粒子生成 粒子更新 右边的发射器 和左边发射器不同的地方 3.4 Texture Sampling 发射器更新 粒子生成 粒子更新 4.1Play Audio Per Particle 系统 第三个发射器 发射器更新 粒子生成 粒子更新 第二个…...
数据结构队列的实现
本章介绍数据结构队列的内容,我们会从队列的定义以及使用和OJ题来了解队列,话不多说,我们来实现吧 队列 1。队列的概念及结构 队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,…...
Gti的基本介绍和使用方式
Git 是一种分布式版本控制系统, 主要用于管理软件开发过程中的代码变更。其基本概念包括: 仓库 (Repository): Git中存储代码的基本单位,即一个代码库。在仓库中可以存储多个分支、标签、提交记录等。 分支 (Branch): Git中的分支是代码的不同开发方向,…...
剑指Offer 24-反转链表
题目描述:定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。 示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL 解题思路: 这道题做过很多次,还是会…...
小研究 - Java虚拟机即时编译器的一种实现原理
深入分析了 Kaffe虚拟机的 JIT(Just-In-Ti…...
【LeetCode】416.分割等和子集
题目 给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。 示例 1: 输入:nums [1,5,11,5] 输出:true 解释:数组可以分割成 [1, 5, 5] 和 [11] 。 示…...
go vet中的那些检测项
go vet 是 Go 语言自带的一个工具,用于分析 Go 代码中的常见错误和潜在问题。它可以检查代码中可能存在的各种问题,例如: 未使用的变量、函数或包 可疑的函数调用 错误的函数签名 程序中的竞态条件 错误的类型转换等 本文意图指令当前go vet所…...
Qt 自定义菜单、右键菜单
在接触Qt这段时间以来,经常遇到菜单项的问题(右键菜单、托盘菜单、按钮菜单等),QMenu用于菜单栏,上下文菜单,弹出菜单等,利用QMenuQAction就可以达到效果! 右键菜单实现:通过重写contextMenuEv…...
VScode 编辑器报错: ‘HelloWorld‘ is declared but its value is never read.
.vue文件被标识红色波浪线;提示: HelloWorld is declared but its value is never read. 问题原因: 因为vue3已经不支持vetur插件。 1、在扩展里面进行搜索Vetur插件,进行禁用或卸载; 2、在 VScode扩展里面搜索并下载…...
如何使用LLM实现文本自动生成视频
推荐:使用 NSDT场景编辑器 助你快速搭建可二次编辑的3D应用场景 介绍 基于扩散的图像生成模型代表了计算机视觉领域的革命性突破。这些进步由Imagen,DallE和MidJourney等模型开创,展示了文本条件图像生成的卓越功能。有关这些模型内部工作的…...
Rust处理JSON
基本操作 Cargo.toml: [package]name "json"version "0.1.0"edition "2021"# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html[dependencies]serde { version "1", features …...
Python如何操作网络爬虫
Python是一种非常强大的编程语言,用于网络爬虫操作也非常方便。Python提供了许多用于构建和操作网络爬虫的库和工具,如BeautifulSoup、Scrapy、Requests等。本文将详细介绍Python如何操作网络爬虫。 一、安装相关库 首先,我们需要安装Python…...
linux文件复制覆盖命令
目录 cp 命令参数2.cp -rf 出现复制不覆盖文件问题3.解决文件复制覆盖提示操作问题,以下四种方式,供大家参考使用。方法1:编写带cp的路径复制覆盖文件方法2:在CP命令前面加一个斜杠\,实现强制覆盖文件方法3:…...
modbus概览
modbus Modbus是Modicon(施耐德)公司于1979年开发的串行通信协议。它最初设计用于公司的可编程逻辑控制器(PLC)。 Modbus是一种开放式协议,支持使用RS232/RS485/RS422协议的串行设备,同时还支持调制解调器…...
KMP算法开荒
文章目录 一 、前言二、 暴力解法三、KMP算法原理3.1 自动子串的指针3.2 跳过多少个字符3.3 next数组 - 暴力3.4 next数组 - 求解 四 KMP实现 一 、前言 字符串匹配 import re print(re.search(www, www.runoob.com).span()) # 在起始位置匹配 print(re.search(com, www.run…...
XXL-JOB(2)
Glue模式 任务以源码的形式去维护调度中心,支持实时编译,无需指定JobHandler。 实际上是继承自JobHandler的java类代码,在执行器中运行,可以使用Resource/Autowire注入执行器里中的其他服务. 在执行器中添加service Service p…...
Linux常用命令_网络命令、关机重启命令
文章目录 1. 网络命令1.1 网络命令: write1.2 网络命令: wall1.3 网络命令: ping1.4 网络命令: ifconfig1.5 网络命令: mail1.6 网络命令: last1.7 网络命令: lastlog1.8 网络命令: traceroute1.9 网络命令: netstat1.10 网络命令: setup1.11 挂载命令 2. 关机重启命令2.1 shut…...
用Cmake build OpenCV后,在VS中查看OpenCV源码的方法(环境VS2022+openCV4.8.0) Part I
用Cmake build OpenCV后,在VS中查看OpenCV源码的方法 Part I 写在最前面,最近这段时间的工作需要用opencv,不仅是调包,还要能够看到opencv的源码。然后就跟着网上的教程实现了一遍,在实现过程中,遇到了不少…...
【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...
什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
