尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

0125_命令模式(Command)

0125_命令模式(Command)
📅 发布时间:2026/6/20 22:47:38

命令模式(Command)

意图

将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化,支持请求的排队、记录日志、撤销等操作。

UML 图

Command

优点

  1. 解耦调用者和接收者:调用者不需要知道接收者的具体实现
  2. 支持命令的排队和日志:可以轻松实现命令队列和日志记录
  3. 支持撤销和重做:通过维护命令历史,可以实现撤销和重做功能
  4. 易于扩展新命令:新增命令不需要修改现有代码
  5. 支持宏命令:可以将多个命令组合成一个复合命令

缺点

  1. 类数量增加:每个命令都需要一个具体的命令类
  2. 复杂度增加:引入了额外的抽象层,增加了系统复杂度
  3. 性能开销:命令对象的创建和管理可能带来一定的性能开销
  4. 内存占用:维护命令历史可能占用较多内存
  5. 过度设计:简单场景下使用可能显得过于复杂

代码示例

以人类指挥机器人执行各种任务为例:

1. 命令接口 (Command Interface)

// 命令接口
public interface Command {void execute();void undo();String getDescription();
}

2. 接收者 (Receiver) - 机器人

// 接收者 - 机器人
public class Robot {private String name;public Robot(String name) {this.name = name;}public void cook(String dish) {System.out.println("🤖 " + name + " 正在烹饪: " + dish);}public void clean(String area) {System.out.println("🧹 " + name + " 正在打扫: " + area);}public void deliver(String item, String location) {System.out.println("📦 " + name + " 正在配送 " + item + " 到 " + location);}public void stopCurrentTask() {System.out.println("⏹️ " + name + " 停止当前任务");}
}

3. 具体命令 (Concrete Commands)

// 烹饪命令
public class CookCommand implements Command {private Robot robot;private String dish;public CookCommand(Robot robot, String dish) {this.robot = robot;this.dish = dish;}@Overridepublic void execute() {robot.cook(dish);}@Overridepublic void undo() {robot.stopCurrentTask();System.out.println("撤销烹饪: " + dish);}@Overridepublic String getDescription() {return "烹饪 " + dish;}
}// 打扫命令
public class CleanCommand implements Command {private Robot robot;private String area;public CleanCommand(Robot robot, String area) {this.robot = robot;this.area = area;}@Overridepublic void execute() {robot.clean(area);}@Overridepublic void undo() {robot.stopCurrentTask();System.out.println("撤销打扫: " + area);}@Overridepublic String getDescription() {return "打扫 " + area;}
}// 配送命令
public class DeliverCommand implements Command {private Robot robot;private String item;private String location;public DeliverCommand(Robot robot, String item, String location) {this.robot = robot;this.item = item;this.location = location;}@Overridepublic void execute() {robot.deliver(item, location);}@Overridepublic void undo() {robot.stopCurrentTask();System.out.println("撤销配送: " + item + " 到 " + location);}@Overridepublic String getDescription() {return "配送 " + item + " 到 " + location;}
}

4. 调用者 (Invoker) - 人类指挥官

// 调用者 - 人类指挥官
public class HumanCommander {private List<Command> commandHistory = new ArrayList<>();private Command currentCommand;public void setCommand(Command command) {this.currentCommand = command;}public void executeCommand() {if (currentCommand != null) {System.out.println("🚀 执行命令: " + currentCommand.getDescription());currentCommand.execute();commandHistory.add(currentCommand);}}public void undoLastCommand() {if (!commandHistory.isEmpty()) {Command lastCommand = commandHistory.remove(commandHistory.size() - 1);System.out.println("↩️ 撤销命令: " + lastCommand.getDescription());lastCommand.undo();}}public void showCommandHistory() {System.out.println("\n📋 命令历史:");for (int i = 0; i < commandHistory.size(); i++) {System.out.println((i + 1) + ". " + commandHistory.get(i).getDescription());}}
}

5. 客户端代码 (Client Code)

public class CommandPatternDemo {public static void main(String[] args) {// 创建接收者 - 机器人Robot kitchenRobot = new Robot("厨房机器人");Robot cleaningRobot = new Robot("清洁机器人");Robot deliveryRobot = new Robot("配送机器人");// 创建具体命令Command cookDinner = new CookCommand(kitchenRobot, "红烧牛肉");Command cleanKitchen = new CleanCommand(cleaningRobot, "厨房");Command deliverPackage = new DeliverCommand(deliveryRobot, "快递", "A栋101");Command cookDessert = new CookCommand(kitchenRobot, "水果沙拉");// 创建调用者 - 人类指挥官HumanCommander commander = new HumanCommander();System.out.println("=== 执行一系列命令 ===");// 执行第一个命令commander.setCommand(cookDinner);commander.executeCommand();// 执行第二个命令commander.setCommand(cleanKitchen);commander.executeCommand();// 执行第三个命令commander.setCommand(deliverPackage);commander.executeCommand();System.out.println("\n=== 撤销上一个命令 ===");commander.undoLastCommand();System.out.println("\n=== 执行新命令 ===");commander.setCommand(cookDessert);commander.executeCommand();// 显示命令历史commander.showCommandHistory();System.out.println("\n=== 批量撤销 ===");commander.undoLastCommand(); // 撤销甜点commander.undoLastCommand(); // 撤销打扫commander.undoLastCommand(); // 撤销烹饪commander.showCommandHistory();}
}

在Java标准库中的应用

命令模式在Java标准库中有多种应用:

  1. Runnable接口
// Runnable就是一个简单的命令模式实现
Runnable task = () -> System.out.println("执行任务");
new Thread(task).start(); // Invoker
  1. Swing的Action接口
Action action = new AbstractAction("点击") {@Overridepublic void actionPerformed(ActionEvent e) {// 命令执行}
};
JButton button = new JButton(action); // Invoker
  1. 线程池执行命令
ExecutorService executor = Executors.newFixedThreadPool(5);
executor.execute(() -> {// 命令执行逻辑
}); // Invoker
  1. Servlet的Service方法
protected void service(HttpServletRequest req, HttpServletResponse resp) {// 根据请求参数选择不同的命令执行
}

总结

命令模式通过将请求封装为对象,实现了请求的发送者和接收者之间的解耦。在人类与机器人的交互场景中,人类作为调用者只需要发出命令,而不需要了解机器人具体如何执行任务。这种模式支持命令的排队、日志记录、撤销重做等功能,非常适合需要支持事务操作或需要记录操作历史的系统。

该模式的灵活性使得系统可以轻松地扩展新的命令类型,而不需要修改现有的调用者代码。虽然会增加一些类的数量,但在需要复杂命令管理的系统中,这种额外的复杂度是值得的。

相关新闻

  • 通过 GitHub 仓库下载微信 Mac Windows 历史版本(Rodert 提供)
  • 使用GoLang执行Shellcode的技术解析
  • cidr Not Available

最新新闻

  • 5分钟终结乱码烦恼:EncodingChecker让文件编码检测变得如此简单
  • 佛山大学在全国 / 省内排名多少?是不是双一流 / 省重点院校? - 寻茫精选
  • 3DS自制软件终极指南:如何使用Universal-Updater一键管理所有应用
  • CentOS 6 Postfix 安装配置实战:从源失效到生产可用
  • 2026年6月沈阳营业性演出许可证一站式代办推荐 - 速递信息
  • 2026年品牌出海跨境电商系统推荐:技术架构与跨境适配深度测评 - 科技焦点

日新闻

  • Visual C++运行库修复终极指南:5分钟快速解决Windows软件启动错误
  • 手把手教你构建统计局地区经济数据爬虫:从环境搭建到数据持久化全指南
  • 2026多Agent深度解析:用AI团队替代单一模型,四种架构实战落地

周新闻

  • Visual C++运行库修复终极指南:5分钟快速解决Windows软件启动错误
  • 手把手教你构建统计局地区经济数据爬虫:从环境搭建到数据持久化全指南
  • 2026多Agent深度解析:用AI团队替代单一模型,四种架构实战落地

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号