什么是命令模式
命令模式Command Pattern 是一种行为型设计模式,它把请求封装成对象,从而将请求的发送者与执行者完全解耦,支持排队、撤销、日志记录等操作。。
模式目标:
解耦命令的发出者(Invoker)与执行者(Receiver)
模式例子
在生活中,比如麦当劳点餐流程,来看看命令模式的经典现实例子:
角色 | 对应命令模式中的角色 |
---|---|
顾客 | 请求发送者 Invoker |
点餐员 | 命令对象 Command |
厨房/厨师 | 实际执行者 Receiver |
点菜单 | 被封装的命令 Request |
顾客(Invoker)下单 → 服务员记录订单(Command) → 厨师(Receiver)执行烹饪操作
- 顾客不关心怎么做菜;
- 厨师不关心是谁点的;
- 服务员中转命令,负责排队、取消、记录等操作。
👉 服务员就是命令模式中的 Command 对象
UML图
通用表示:
针对本例:
Java 命令模式完整实现
我们模拟一个遥控器控制家电的命令模式案例。
命令接口
Command
public interface OrderCommand {void execute();
}
厨师类(实际执行者 Receiver)
public class Chef {public void makeBurger() {System.out.println("🍔 厨师正在制作汉堡!");}public void makeFries() {System.out.println("🍟 厨师正在炸薯条!");}
}
实际执行者 Receiver
public class BurgerOrder implements OrderCommand {private Chef chef;public BurgerOrder(Chef chef) {this.chef = chef;}@Overridepublic void execute() {chef.makeBurger();}
}public class FriesOrder implements OrderCommand {private Chef chef;public FriesOrder(Chef chef) {this.chef = chef;}@Overridepublic void execute() {chef.makeFries();}
}
服务员类(Invoker)
public class Waiter {private List<OrderCommand> orderList = new ArrayList<>();public void takeOrder(OrderCommand command) {orderList.add(command);}public void submitOrders() {System.out.println("🧾 服务员提交订单给厨房...");for (OrderCommand command : orderList) {command.execute();}orderList.clear();}
}
客户端测试代码
public class Customer {public static void main(String[] args) {Chef chef = new Chef();// 创建命令对象OrderCommand burger = new BurgerOrder(chef);OrderCommand fries = new FriesOrder(chef);// 顾客下单,服务员记录Waiter waiter = new Waiter();waiter.takeOrder(burger);waiter.takeOrder(fries);// 服务员提交订单,厨师开始执行waiter.submitOrders();}
}
运行结果
命令模式的优点与用途
优点
优点 | 描述 |
---|---|
解耦调用者和接收者 | 请求发送者不关心具体怎么做 |
支持撤销与日志记录 | 可记录命令序列,回滚操作 |
支持命令组合与排队 | 命令对象可以存入队列或组合 |
实际应用场景
应用场景 | 示例说明 |
---|---|
UI按钮命令绑定 | Swing按钮点击执行某个命令 |
事务操作/回滚 | 数据库事务日志 |
宏命令/组合操作 | Photoshop一键动作 |
消息队列处理 | Kafka、RabbitMQ 消息处理器 |
总结
- 命令模式是高内聚、低耦合的典范;
- 适合对请求进行记录、排队、撤销等处理;
- 可广泛应用于 UI 控件回调、遥控设备、游戏命令、数据库事务管理等场景。
参考
《23种设计模式概览》
附
@startuml
title Java命令模式结构图interface Command {+execute()
}class ConcreteCommand {-receiver: Receiver+execute()
}class Receiver {+action()
}class Invoker {+setCommand(cmd: Command)+invoke()
}Command <|-- ConcreteCommand
ConcreteCommand --> Receiver
Invoker --> Command@enduml