阿里P9大佬分享:如何让代码更加灵活
面试官: 你好,今天我们要讨论的是命令模式。首先,你能解释一下什么是命令模式吗?
求职者: 当然可以。命令模式是一种行为设计模式,它将一个请求封装成一个对象,从而让你使用不同的请求、队列或者日志请求来参数化其他对象。命令模式也支持可撤销的操作。
面试官: 很好。那么,你能给我举一个命令模式的实际编程例子吗?
求职者: 当然可以。就像遥控器一样,它有很多按钮,每个按钮背后都有一个命令。在编程中,我们可以创建一个命令接口,这个接口定义了执行操作的方法。然后,我们可以为每个操作创建具体的命令类。这些类包含了执行操作所必需的信息和方法。
例如,在一个游戏模拟器中,我们可以有启动和停止游戏的命令。启动命令会调用游戏控制台的start_game
方法,而停止命令会调用stop_game
方法。
面试官: 那么,命令模式如何实现撤销和恢复操作呢?
求职者: 要实现撤销和恢复操作,命令对象需要存储原始状态信息,以便可以恢复到执行命令之前的状态。通常,每个命令类会有一个undo
方法来回滚操作。在执行操作时,命令对象被添加到历史记录中。当执行撤销操作时,可以从历史记录中获取最新的命令并调用其undo
方法。
面试官: 很好。那么,你认为命令模式的优点是什么?
求职者: 命令模式的优点包括:
- 解耦发送者和接收者:发送命令的对象不需要知道接收者是谁,也不需要知道被执行的操作的具体细节。
- 扩展性:可以很容易地添加新的命令,因为命令模式使用命令作为中间层。
- 组合命令:可以组合多个命令来实现宏命令。
- 支持撤销和恢复:命令模式可以通过实现
undo
方法来支持撤销和恢复操作。
面试官: 非常好。你提到了命令模式的关键优点。那么,命令模式是如何将创建型模式和行为型模式交织在一起的呢?
求职者: 命令模式可以看作是创建型模式和行为型模式的结合。从创建型模式的角度来看,命令模式涉及到创建具体命令对象,并与特定的接收者关联。而从行为型模式的角度来看,命令模式定义了一个执行操作的接口,使得发送者和接收者之间的请求调用可以解耦。
面试官: 很好,现在让我们来探讨一下命令模式如何支持宏命令的组合。首先,你能解释一下什么是宏命令吗?
求职者: 当然可以。宏命令是一组命令的集合,它可以一起被执行。在命令模式中,我们可以创建一个宏命令对象,这个对象内部包含了一组命令对象。当执行宏命令时,它会依次执行内部的每个命令。
面试官: 那你能用代码示例来说明如何实现宏命令吗?
求职者: 当然。我们可以创建一个MacroCommand
类,它实现了Command
接口。这个类内部维护了一个命令列表,并提供了添加命令的方法。在execute
方法中,它会遍历并执行所有的命令。
class MacroCommand implements Command {private List<Command> commands;public MacroCommand() {commands = new ArrayList<>();}public void addCommand(Command command) {commands.add(command);}public void execute() {for (Command command : commands) {command.execute();}}public void undo() {// Optional: Implement undo in reverse order if neededListIterator<Command> iterator = commands.listIterator(commands.size());while (iterator.hasPrevious()) {iterator.previous().undo();}}
}
在这个例子中,MacroCommand
可以包含任何数量的命令对象。当调用它的execute
方法时,它会执行所有添加的命令。我们还可以实现undo
方法,以便可以撤销宏命令中的所有操作。
面试官: 现在,我们来看一个具体的例子,说明如何在命令模式中实现命令的撤销功能。你能给我一个简单的代码示例吗?
求职者: 当然可以。假设我们有一个简单的文本编辑器,我们可以添加文本和删除文本。我们将创建一个添加文本的命令,并实现一个撤销功能,这样我们就可以撤销添加的文本。
首先,我们定义一个Command
接口,它包含execute
和undo
方法:
interface Command {void execute();void undo();
}
然后,我们创建一个AddTextCommand
类,它实现了Command
接口:
class AddTextCommand implements Command {private String textToAdd;private TextEditor editor;public AddTextCommand(String textToAdd, TextEditor editor) {this.textToAdd = textToAdd;this.editor = editor;}public void execute() {editor.addText(textToAdd);}public void undo() {editor.removeText(textToAdd);}
}
接下来,我们定义TextEditor
类,它包含添加和删除文本的功能:
class TextEditor {private StringBuilder text = new StringBuilder();public void addText(String textToAdd) {text.append(textToAdd);}public void removeText(String textToRemove) {int index = text.lastIndexOf(textToRemove);if (index != -1) {text.delete(index, index + textToRemove.length());}}public String getText() {return text.toString();}
}
现在,我们需要一个机制来执行和撤销命令,我们创建一个TextEditorDriver
类:
class TextEditorDriver {private Stack<Command> commandHistory = new Stack<>();public void executeCommand(Command cmd) {cmd.execute();commandHistory.push(cmd);}public void undoLastCommand() {if (!commandHistory.isEmpty()) {Command lastCmd = commandHistory.pop();lastCmd.undo();}}
}
最后,我们在main
方法中模拟命令的执行和撤销:
public class Main {public static void main(String[] args) {TextEditor editor = new TextEditor();TextEditorDriver driver = new TextEditorDriver();Command addTextCmd = new AddTextCommand("Hello, World!", editor);driver.executeCommand(addTextCmd);System.out.println("Text after add command: " + editor.getText());driver.undoLastCommand();System.out.println("Text after undo: " + editor.getText());}
}
在这个例子中,我们添加了文本"Hello, World!"到文本编辑器,然后我们执行了撤销操作,这将移除我们刚刚添加的文本。
面试官: 好的,让我们离开文本编辑器,看看命令模式中撤销功能在其他场景中的应用。你能给我一个不同的例子吗?
求职者: 当然。让我们考虑一个家居自动化系统,比如智能灯泡的控制。我们可以开灯和关灯,并且我们希望能够撤销这些操作。
首先,我们定义一个Command
接口:
interface Command {void execute();void undo();
}
接着,我们创建Light
类和两个命令:LightOnCommand
和LightOffCommand
:
class Light {private boolean isOn = false;public void toggleLight() {isOn = !isOn;if (isOn) {System.out.println("Light is ON");} else {System.out.println("Light is OFF");}}
}class LightOnCommand implements Command {private Light light;public LightOnCommand(Light light) {this.light = light;}public void execute() {light.toggleLight();}public void undo() {light.toggleLight();}
}class LightOffCommand implements Command {private Light light;public LightOffCommand(Light light) {this.light = light;}public void execute() {light.toggleLight();}public void undo() {light.toggleLight();}
}
然后,我们创建一个控制器,它可以执行命令并且支持撤销:
class RemoteControl {private Command lastCommand;public void submit(Command command) {command.execute();lastCommand = command;}public void undoLastCommand() {if (lastCommand != null) {lastCommand.undo();}}
}
最后,我们在main
方法中模拟命令的执行和撤销:
public class SmartHomeDemo {public static void main(String[] args) {Light livingRoomLight = new Light();Command lightOn = new LightOnCommand(livingRoomLight);Command lightOff = new LightOffCommand(livingRoomLight);RemoteControl remoteControl = new RemoteControl();remoteControl.submit(lightOn); // Light is ONremoteControl.submit(lightOff); // Light is OFF// Oops, didn't mean to turn it off. Let's undo that.remoteControl.undoLastCommand(); // Light is ON}
}
在这个例子中,我们通过RemoteControl
执行了开灯和关灯的命令,并且使用撤销功能来撤销关灯的操作。
面试官: 很好,这个例子清楚地展示了命令模式在家居自动化系统中的撤销功能。你展示了命令模式的灵活性和命令撤销的实用性。这就是我们今天要讨论的全部内容,谢谢你的参与。
相关文章:
阿里P9大佬分享:如何让代码更加灵活
面试官: 你好,今天我们要讨论的是命令模式。首先,你能解释一下什么是命令模式吗? 求职者: 当然可以。命令模式是一种行为设计模式,它将一个请求封装成一个对象,从而让你使用不同的请求、队列或者日志请求来参数化其他…...
SpringBoot中加载配置文件的优先级
在Spring Boot中,加载配置文件的优先级按照以下顺序进行,后续的配置会覆盖之前的配置: 默认属性:这些属性在Spring Boot本身中定义,并且通常是不可变的。它们作为后备值。 应用程序属性:这些属性在应用程序…...

Mysql命令行客户端
命令行客户端 操作数据库操作数据表 操作数据库 mysql> create database mike charsetutf8; Query OK, 1 row affected (0.01 sec) mysql> show databases; -------------------- | Database | -------------------- | information_schema | | mike …...

开源的python 游戏开发库介绍
本文将为您详细讲解开源的 Python 游戏开发库,以及它们的特点、区别和应用场景。Python 社区提供了多种游戏开发库,这些库可以帮助您在 Python 应用程序中实现游戏逻辑、图形渲染、声音处理等功能。 1. Pygame 特点 - 基于 Python 的游戏开发库。…...

批量提取PDF指定区域内容到 Excel 以及根据PDF里面第一页的标题来批量重命名-附思路和代码实现
首先说明下,PDF需要是电子版本的,不能是图片或者无法选中的那种。 需求1:假如我有一批数量比较多的同样格式的PDF电子文档,需要把特定多个区域的数字或者文字提取出来 需求2:我有一批PDF文档,但是文件的名…...

PCM会重塑汽车OTA格局吗(1)
目录 1.汽车OTA概述 2.ST如何考虑OTA? 2.1 Stellar四大亮点 2.2 PCM技术视角下的OTA 3.小结 1.汽车OTA概述 随着智能网联汽车的飞速发展,汽车OTA也越来越盛行; 目前来讲OTA分为FOTA和SOTA(Software-over-the-air)两种,区别…...

Intel® Extension for PyTorch*详细安装教程
最近在研究Intel的pytorch的加速拓展Intel Extension for PyTorch*,但是发现官网的文档全是英文的,不太好找安装教程。所以特此分享Intel Extension for PyTorch*的详细安装教程。 文章目录 一、安装所需系统要求1.1 硬件需求1.2 软件需求 二、准备2.1 安装驱动程序…...

云上攻防-云产品篇堡垒机场景JumpServer绿盟SASTeleport麒麟齐治
知识点 1、云产品-堡垒机-产品介绍&攻击事件 2、云产品-堡垒机-安全漏洞&影响产品 章节点: 云场景攻防:公有云,私有云,混合云,虚拟化集群,云桌面等 云厂商攻防:阿里云,腾讯…...

【顶刊|修正】多区域综合能源系统热网建模及系统运行优化【复现+延伸】
目录 主要内容 部分代码 结果一览 下载链接 主要内容 该程序复现《多区域综合能源系统热网建模及系统运行优化》模型并进一步延伸,基于传热学的基本原理建立了区域热网能量传输通用模型,对热网热损方程线性化实现热网能量流建模࿰…...
使用Numpy手工模拟梯度下降算法
代码 import numpy as np # Compute every step manually# Linear regression # f w * x # here : f 2 * x X np.array([1, 2, 3, 4], dtypenp.float32) Y np.array([2, 4, 6, 8], dtypenp.float32)w 0.0# model output def forward(x):return w * x# loss MSE def loss…...

金融数据采集与风险管理:Open-Spider工具的应用与实践
一、项目介绍 在当今快速发展的金融行业中,新的金融产品和服务层出不穷,为银行业务带来了巨大的机遇和挑战。为了帮助银行员工更好地应对这些挑战,我们曾成功实施了一个创新的项目,该项目采用了先进的爬虫技术,通过ope…...

鸿蒙Harmony应用开发—ArkTS声明式开发(通用属性:动态属性设置)
动态设置组件的属性,支持开发者在属性设置时使用if/else语法,且根据需要使用多态样式设置属性。 说明: 从API Version 11开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 attributeModifier attributeMo…...

Vue class和style绑定:动态美化你的组件
🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…...
[C++] Windows中字符串函数的种类
文章目录 C标准库函数VC CRT函数Win32 APILinux C标准库函数 #include || #include <string.h> || #include 都可以使用以下函数: char *strcpy(char *dest, const char *src) //将Src字符串拷贝到Dst字符串地址。没有目标内存大小检查,可能会导致…...

Django工具
一、分页器介绍 1.1、介绍 分页,就是当我们在页面中显示一些信息列表,内容过多,一个页面显示不完,需要分成多个页面进行显示时,使用的技术就是分页技术 在django项目中,一般是使用3种分页的技术: 自定义分页功能,所有的分页功能都是自己实现django的插件 django-pagin…...

vue ui Starting GUI 图形化配置web新项目
前言:在vue框架里面, 以往大家都是习惯用命令行 vue create 、vue init webpack创建新前端项目,而vue ui是一个可视化的图形界面,对于新手来说更加友好了,不但可以创建、管理、还可以更新vue项目,也可以下载…...
Unity InputField宽度自适应内容
在Unity中,InputField在我们输入内容时,只会显示适应初始宽度的最新内容,或者自定义长度内容。 那么,要实现宽度自适应内容就需要另寻他法了。 以下是通过一个控制脚本来实现的一个简单方法。 直接上脚本: using S…...

加快代码审查的 7 个最佳实践
目录 前言 1-保持小的拉取请求 2-使用拉取请求模板 3-实施响应时间 SLA 4-培训初级和中级工程师 5-设置持续集成管道 6-使用拉取请求审查应用程序 7-生成图表以可视化您的代码更改 前言 代码审查可能会很痛苦软件工程师经常抱怨审查过程缓慢,延迟下游任务&…...
C++读写Excel(xlnt库的使用)
一、简介 官网:https://github.com/tfussell/xlnt Cross-platform user-friendly xlsx library for C11 xlnt is a modern C library for manipulating spreadsheets in memory and reading/writing them from/to XLSX files as described in ECMA 376 4th edition…...
【工具】conda常用命令
Conda 是一个流行的包管理器和环境管理器,用于安装、部署和管理软件包及其依赖项。 创建环境: conda create --name myenv 这将创建一个名为 myenv 的新环境。 激活环境: conda activate myenv 这会激活名为 myenv 的环境。在 Windows 上&am…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...

通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...