阿坝藏族羌族自治州网站建设_网站建设公司_建站流程_seo优化
2025/12/23 19:08:16 网站建设 项目流程

目录

一、命令模式(Command Pattern)核心定义

二、命令模式的核心角色

三、命令模式的典型结构与代码示例

1. 极简代码实现(订单场景)

步骤 1:定义接收者(真正执行业务逻辑)

步骤 2:定义抽象命令接口

步骤 3:实现具体命令(绑定接收者和操作)

步骤 4:定义调用者(触发命令执行)

步骤 5:客户端(组装命令、调用者、接收者)

2. 关键特性解析

四、命令模式的扩展特性(高级用法)

1. 命令的撤销 / 重做(Undo/Redo)

2. 命令队列(批量执行)

3. 宏命令(组合命令)

五、命令模式的典型应用场景

框架中的典型案例:Spring MVC 的 Command 模式

六、命令模式 vs 策略模式(易混淆对比)

七、命令模式的优缺点

优点

缺点

八、使用注意事项

总结


一、命令模式(Command Pattern)核心定义

命令模式是一种行为型设计模式,核心思想是:将 “请求” 封装为一个独立的对象(命令对象),这个对象包含执行请求的所有信息(如接收者、方法、参数);请求的发送者(调用者)无需知道请求的具体处理逻辑,只需调用命令对象的执行方法即可

简单来说,命令模式把 “做什么” 和 “谁去做、怎么做” 分离开:

  • 发送者(Invoker):只负责触发命令执行,不关心命令的具体实现;
  • 命令对象(Command):封装了具体的操作和接收者;
  • 接收者(Receiver):真正执行命令的对象(包含核心业务逻辑)。

核心价值:解耦请求的发起者和执行者,支持请求的参数化、队列化、撤销 / 重做等扩展。

二、命令模式的核心角色

命令模式包含 4 个核心角色(以 Java 为例),角色分工清晰且职责单一:

角色核心职责典型示例(订单场景)
抽象命令(Command)定义命令的统一接口,通常包含execute()方法(执行命令),可选undo()(撤销命令)OrderCommand接口(含execute()
具体命令(ConcreteCommand)实现抽象命令接口,绑定 “接收者” 和 “具体操作”,调用接收者的方法完成命令CreateOrderCommand/CancelOrderCommand
调用者(Invoker)持有命令对象,触发命令执行(无需知道命令的具体逻辑)OrderInvoker(订单处理器,调用command.execute()
接收者(Receiver)包含具体的业务逻辑(如创建订单、取消订单),是命令的实际执行者OrderService(包含createOrder()/cancelOrder()
客户端(Client)创建命令对象,绑定接收者,将命令对象传递给调用者业务代码中构建CreateOrderCommand,并设置给OrderInvoker

三、命令模式的典型结构与代码示例

1. 极简代码实现(订单场景)

以 “电商订单操作” 为例,实现命令模式的核心结构:

步骤 1:定义接收者(真正执行业务逻辑)

java

运行

// 接收者:订单服务(包含核心业务逻辑) public class OrderService { // 创建订单 public void createOrder(String orderId, String userId) { System.out.println("接收者执行:创建订单,订单ID=" + orderId + ",用户ID=" + userId); } // 取消订单 public void cancelOrder(String orderId) { System.out.println("接收者执行:取消订单,订单ID=" + orderId); } }
步骤 2:定义抽象命令接口

java

运行

// 抽象命令:订单操作命令 public interface OrderCommand { // 执行命令 void execute(); }
步骤 3:实现具体命令(绑定接收者和操作)

java

运行

// 具体命令1:创建订单命令 public class CreateOrderCommand implements OrderCommand { // 绑定接收者 private OrderService orderService; // 命令所需参数 private String orderId; private String userId; // 构造器注入接收者和参数 public CreateOrderCommand(OrderService orderService, String orderId, String userId) { this.orderService = orderService; this.orderId = orderId; this.userId = userId; } @Override public void execute() { // 调用接收者的具体方法 orderService.createOrder(orderId, userId); } } // 具体命令2:取消订单命令 public class CancelOrderCommand implements OrderCommand { private OrderService orderService; private String orderId; public CancelOrderCommand(OrderService orderService, String orderId) { this.orderService = orderService; this.orderId = orderId; } @Override public void execute() { orderService.cancelOrder(orderId); } }
步骤 4:定义调用者(触发命令执行)

java

运行

// 调用者:订单处理器(只负责触发命令,不关心具体逻辑) public class OrderInvoker { // 持有当前要执行的命令 private OrderCommand command; // 设置命令(支持动态切换命令) public void setCommand(OrderCommand command) { this.command = command; } // 执行命令 public void executeCommand() { if (command != null) { command.execute(); } else { System.out.println("未设置订单命令"); } } }
步骤 5:客户端(组装命令、调用者、接收者)

java

运行

public class Client { public static void main(String[] args) { // 1. 创建接收者(核心业务逻辑) OrderService orderService = new OrderService(); // 2. 创建具体命令(绑定接收者和参数) OrderCommand createCommand = new CreateOrderCommand(orderService, "ORDER001", "USER001"); OrderCommand cancelCommand = new CancelOrderCommand(orderService, "ORDER001"); // 3. 创建调用者 OrderInvoker invoker = new OrderInvoker(); // 4. 执行创建订单命令 invoker.setCommand(createCommand); invoker.executeCommand(); // 输出:接收者执行:创建订单,订单ID=ORDER001,用户ID=USER001 // 5. 执行取消订单命令(动态切换命令) invoker.setCommand(cancelCommand); invoker.executeCommand(); // 输出:接收者执行:取消订单,订单ID=ORDER001 } }

2. 关键特性解析

  • 解耦性:调用者(OrderInvoker)只知道调用execute(),无需知道是 “创建订单” 还是 “取消订单”;接收者(OrderService)只负责执行业务逻辑,无需知道谁触发;
  • 命令参数化:通过构造器将参数传入命令对象,支持不同参数的命令复用;
  • 动态切换:调用者可随时切换命令(如从创建订单切换为取消订单);
  • 可扩展:新增 “修改订单” 命令,只需新增ModifyOrderCommand,无需修改调用者和接收者。

四、命令模式的扩展特性(高级用法)

1. 命令的撤销 / 重做(Undo/Redo)

命令模式天然支持撤销 / 重做,只需在抽象命令中新增undo()方法:

java

运行

// 扩展抽象命令:支持撤销 public interface OrderCommand { void execute(); void undo(); // 撤销命令 } // 具体命令实现撤销逻辑 public class CreateOrderCommand implements OrderCommand { // 省略原有代码... @Override public void undo() { // 撤销创建订单:调用取消订单方法 orderService.cancelOrder(orderId); } } // 调用者扩展撤销方法 public class OrderInvoker { // 记录已执行的命令(用于撤销) private List<OrderCommand> commandHistory = new ArrayList<>(); public void executeCommand() { if (command != null) { command.execute(); commandHistory.add(command); // 记录命令 } } // 撤销最后一次执行的命令 public void undoLastCommand() { if (!commandHistory.isEmpty()) { OrderCommand lastCommand = commandHistory.remove(commandHistory.size() - 1); lastCommand.undo(); } } } // 客户端测试撤销 public class Client { public static void main(String[] args) { OrderService orderService = new OrderService(); OrderCommand createCommand = new CreateOrderCommand(orderService, "ORDER001", "USER001"); OrderInvoker invoker = new OrderInvoker(); invoker.setCommand(createCommand); invoker.executeCommand(); // 创建订单 invoker.undoLastCommand(); // 撤销:取消订单 } }

2. 命令队列(批量执行)

调用者可维护一个命令队列,批量执行多个命令,适用于 “批量操作” 场景(如批量创建订单):

java

运行

public class OrderInvoker { // 命令队列 private Queue<OrderCommand> commandQueue = new LinkedList<>(); // 添加命令到队列 public void addCommand(OrderCommand command) { commandQueue.offer(command); } // 批量执行队列中的命令 public void executeBatch() { while (!commandQueue.isEmpty()) { OrderCommand command = commandQueue.poll(); command.execute(); } } } // 客户端测试批量执行 public class Client { public static void main(String[] args) { OrderService orderService = new OrderService(); OrderInvoker invoker = new OrderInvoker(); // 添加多个命令到队列 invoker.addCommand(new CreateOrderCommand(orderService, "ORDER001", "USER001")); invoker.addCommand(new CreateOrderCommand(orderService, "ORDER002", "USER002")); invoker.addCommand(new CancelOrderCommand(orderService, "ORDER001")); // 批量执行 invoker.executeBatch(); } }

3. 宏命令(组合命令)

将多个命令组合为一个 “宏命令”,执行宏命令即执行所有子命令,符合 “组合模式 + 命令模式” 的结合:

java

运行

// 宏命令:批量执行多个订单命令 public class BatchOrderCommand implements OrderCommand { // 子命令列表 private List<OrderCommand> subCommands = new ArrayList<>(); // 添加子命令 public void addSubCommand(OrderCommand command) { subCommands.add(command); } @Override public void execute() { for (OrderCommand command : subCommands) { command.execute(); } } } // 客户端测试宏命令 public class Client { public static void main(String[] args) { OrderService orderService = new OrderService(); // 创建子命令 OrderCommand cmd1 = new CreateOrderCommand(orderService, "ORDER001", "USER001"); OrderCommand cmd2 = new CreateOrderCommand(orderService, "ORDER002", "USER002"); // 创建宏命令 BatchOrderCommand batchCmd = new BatchOrderCommand(); batchCmd.addSubCommand(cmd1); batchCmd.addSubCommand(cmd2); // 执行宏命令 batchCmd.execute(); } }

五、命令模式的典型应用场景

命令模式在框架和业务开发中广泛使用,核心场景是 “需要将请求封装、解耦发送者和执行者,或支持请求的队列化、撤销 / 重做”:

场景命令模式体现
Spring MVC HandlerController作为命令对象,封装了请求处理逻辑;DispatcherServlet作为调用者,触发Controller执行(handleRequest
MyBatis MapperMapper 接口的方法封装为MappedStatement(命令对象),Executor作为调用者,触发 SQL 执行(接收者是StatementHandler
图形界面(GUI)操作按钮点击事件封装为命令(如 “复制”“粘贴” 命令),按钮是调用者,操作系统底层是接收者,支持撤销 / 重做
任务调度(如 Quartz)调度任务封装为Job(命令对象),Scheduler作为调用者,触发任务执行,支持任务队列、重试
事务操作事务的 “提交”“回滚” 封装为命令,事务管理器作为调用者,支持批量事务执行、回滚(撤销)
远程调用(RPC)调用请求封装为命令对象(包含接口名、方法名、参数),客户端是调用者,服务端是接收者

框架中的典型案例:Spring MVC 的 Command 模式

  • 抽象命令Handler接口(如ControllerHttpRequestHandler);
  • 具体命令:自定义@Controller类(如UserController);
  • 调用者DispatcherServlet(调用HandlerAdapter.handle()执行命令);
  • 接收者Controller内部的Service/DAO层(真正执行业务逻辑)。

执行流程:

plaintext

客户端请求 → DispatcherServlet(调用者)→ 匹配 Controller(命令对象)→ Controller 调用 Service(接收者)→ 处理请求

六、命令模式 vs 策略模式(易混淆对比)

命令模式和策略模式都体现 “封装行为”,但核心目标不同,需重点区分:

维度命令模式策略模式
核心目的解耦 “请求发送者” 和 “执行者”,支持请求的封装、队列、撤销封装不同的算法,让算法可动态切换,聚焦 “怎么做”
角色关系命令对象绑定接收者(执行者),调用者不依赖接收者策略对象自身包含算法,上下文(调用者)直接依赖策略对象
行为特性命令是 “动作”(如创建订单),可记录、撤销、批量执行策略是 “算法”(如排序算法、支付方式),无撤销 / 队列特性
示例按钮点击命令、订单操作命令排序策略(冒泡 / 快排)、支付策略(微信 / 支付宝)

七、命令模式的优缺点

优点

  1. 解耦性:发送者和执行者完全解耦,新增命令无需修改调用者和接收者;
  2. 扩展性:新增命令只需实现抽象命令接口,符合 “开闭原则”;
  3. 灵活性:支持命令的队列化、批量执行、撤销 / 重做、宏命令组合;
  4. 可追踪:可记录命令执行日志,便于审计和问题排查。

缺点

  1. 类膨胀:每个具体命令都需创建一个类,命令数量多会导致类数量激增;
  2. 复杂度提升:引入命令对象、调用者等角色,增加系统复杂度;
  3. 性能损耗:命令的封装和传递会带来少量性能开销(可忽略,除非高频调用)。

八、使用注意事项

  1. 避免过度设计:简单场景(如直接调用方法)无需使用命令模式,仅在需要 “解耦、撤销、队列” 时使用;
  2. 命令参数复用:可通过命令对象的参数化,复用同一命令类处理不同参数(如CreateOrderCommand适配不同订单 ID);
  3. 撤销 / 重做的边界:撤销逻辑需保证幂等性(如撤销 “创建订单” 需确保订单确实存在);
  4. 结合其他模式:命令模式可与组合模式(宏命令)、备忘录模式(保存命令状态用于撤销)、责任链模式(命令传递)结合使用。

总结

命令模式的核心是 “将请求封装为对象”,核心价值在于解耦请求的发起者和执行者,并支持请求的灵活扩展(队列、撤销、批量执行)。它在框架设计(Spring MVC、MyBatis)、GUI 开发、任务调度等场景中不可或缺,是解决 “请求封装与解耦” 的最优模式之一。

掌握命令模式的关键是理解 “命令对象” 的核心作用:它既是发送者和执行者之间的桥梁,也是实现 “可扩展、可追踪、可撤销” 请求处理的核心载体。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询