海南城乡住房建设厅网站,网站cdn自己做,阿里企业邮箱登录,做漫画网站目录 一、命令模式#xff08;Command Pattern#xff09;核心定义
二、命令模式的核心角色
三、命令模式的典型结构与代码示例
1. 极简代码实现#xff08;订单场景#xff09;
步骤 1#xff1a;定义接收者#xff08;真正执行业务逻辑#xff09;
步骤 2#x…目录一、命令模式Command Pattern核心定义二、命令模式的核心角色三、命令模式的典型结构与代码示例1. 极简代码实现订单场景步骤 1定义接收者真正执行业务逻辑步骤 2定义抽象命令接口步骤 3实现具体命令绑定接收者和操作步骤 4定义调用者触发命令执行步骤 5客户端组装命令、调用者、接收者2. 关键特性解析四、命令模式的扩展特性高级用法1. 命令的撤销 / 重做Undo/Redo2. 命令队列批量执行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(); // 输出接收者执行创建订单订单IDORDER001用户IDUSER001 // 5. 执行取消订单命令动态切换命令 invoker.setCommand(cancelCommand); invoker.executeCommand(); // 输出接收者执行取消订单订单IDORDER001 } }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 ListOrderCommand 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 QueueOrderCommand 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 ListOrderCommand 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执行handleRequestMyBatis MapperMapper 接口的方法封装为MappedStatement命令对象Executor作为调用者触发 SQL 执行接收者是StatementHandler图形界面GUI操作按钮点击事件封装为命令如 “复制”“粘贴” 命令按钮是调用者操作系统底层是接收者支持撤销 / 重做任务调度如 Quartz调度任务封装为Job命令对象Scheduler作为调用者触发任务执行支持任务队列、重试事务操作事务的 “提交”“回滚” 封装为命令事务管理器作为调用者支持批量事务执行、回滚撤销远程调用RPC调用请求封装为命令对象包含接口名、方法名、参数客户端是调用者服务端是接收者框架中的典型案例Spring MVC 的 Command 模式抽象命令Handler接口如Controller、HttpRequestHandler具体命令自定义Controller类如UserController调用者DispatcherServlet调用HandlerAdapter.handle()执行命令接收者Controller内部的Service/DAO层真正执行业务逻辑。执行流程plaintext客户端请求 → DispatcherServlet调用者→ 匹配 Controller命令对象→ Controller 调用 Service接收者→ 处理请求六、命令模式 vs 策略模式易混淆对比命令模式和策略模式都体现 “封装行为”但核心目标不同需重点区分维度命令模式策略模式核心目的解耦 “请求发送者” 和 “执行者”支持请求的封装、队列、撤销封装不同的算法让算法可动态切换聚焦 “怎么做”角色关系命令对象绑定接收者执行者调用者不依赖接收者策略对象自身包含算法上下文调用者直接依赖策略对象行为特性命令是 “动作”如创建订单可记录、撤销、批量执行策略是 “算法”如排序算法、支付方式无撤销 / 队列特性示例按钮点击命令、订单操作命令排序策略冒泡 / 快排、支付策略微信 / 支付宝七、命令模式的优缺点优点解耦性发送者和执行者完全解耦新增命令无需修改调用者和接收者扩展性新增命令只需实现抽象命令接口符合 “开闭原则”灵活性支持命令的队列化、批量执行、撤销 / 重做、宏命令组合可追踪可记录命令执行日志便于审计和问题排查。缺点类膨胀每个具体命令都需创建一个类命令数量多会导致类数量激增复杂度提升引入命令对象、调用者等角色增加系统复杂度性能损耗命令的封装和传递会带来少量性能开销可忽略除非高频调用。八、使用注意事项避免过度设计简单场景如直接调用方法无需使用命令模式仅在需要 “解耦、撤销、队列” 时使用命令参数复用可通过命令对象的参数化复用同一命令类处理不同参数如CreateOrderCommand适配不同订单 ID撤销 / 重做的边界撤销逻辑需保证幂等性如撤销 “创建订单” 需确保订单确实存在结合其他模式命令模式可与组合模式宏命令、备忘录模式保存命令状态用于撤销、责任链模式命令传递结合使用。总结命令模式的核心是 “将请求封装为对象”核心价值在于解耦请求的发起者和执行者并支持请求的灵活扩展队列、撤销、批量执行。它在框架设计Spring MVC、MyBatis、GUI 开发、任务调度等场景中不可或缺是解决 “请求封装与解耦” 的最优模式之一。掌握命令模式的关键是理解 “命令对象” 的核心作用它既是发送者和执行者之间的桥梁也是实现 “可扩展、可追踪、可撤销” 请求处理的核心载体。