# 命令模式
# 概念
命令模式一种行为型模式,它将请求封装为对象,使请求的发送者与接收者解耦。通过参数化请求、支持队列、日志记录、撤销/重做等功能,增强系统的灵活性和扩展性。
# 作用
1.解耦请求发送者与接收者:调用者仅依赖抽象命令接口,无需知道具体操作实现。
2.支持动态功能扩展:新增命令时无需修改现有代码,符合开闭原则。
3.实现操作回滚:通过undo()
方法支持撤销功能。
4.增强控制能力:可组合多个命令形成宏命令,或实现延迟执行、事务管理。
# 场景
1.需要解耦请求发起方与执行方。
2.要求支持命令队列、批量执行或事务回滚。
3.需实现撤销/重做、日志记录等高级功能。
4.希望动态指定或组合多个请求操作。
# 举例
// 命令接口
interface Command {
void execute();
void undo();
}
// 接收者(库存管理)
class PhoneInventory {
private int stock = 10;
public void buyPhones(int quantity) {
stock += quantity;
System.out.println("采购成功,当前库存:" + stock);
}
public void sellPhones(int quantity) {
if(stock >= quantity) {
stock -= quantity;
System.out.println("销售成功,当前库存:" + stock);
} else {
System.out.println("库存不足,销售失败");
}
}
}
// 具体命令:采购
class BuyCommand implements Command {
private PhoneInventory inventory;
private int quantity;
public BuyCommand(PhoneInventory inventory, int quantity) {
this.inventory = inventory;
this.quantity = quantity;
}
@Override
public void execute() {
inventory.buyPhones(quantity);
}
@Override
public void undo() {
inventory.sellPhones(quantity);
}
}
// 具体命令:销售
class SellCommand implements Command {
private PhoneInventory inventory;
private int quantity;
public SellCommand(PhoneInventory inventory, int quantity) {
this.inventory = inventory;
this.quantity = quantity;
}
@Override
public void execute() {
inventory.sellPhones(quantity);
}
@Override
public void undo() {
inventory.buyPhones(quantity);
}
}
// 调用者(命令处理器)
class OrderProcessor {
private List<Command> commands = new ArrayList<>();
public void addCommand(Command command) {
commands.add(command);
}
public void processOrders() {
for(Command cmd : commands) {
cmd.execute();
}
commands.clear();
}
}
// 客户端使用
public class Main {
public static void main(String[] args) {
PhoneInventory inventory = new PhoneInventory();
OrderProcessor processor = new OrderProcessor();
processor.addCommand(new BuyCommand(inventory, 5));
processor.addCommand(new SellCommand(inventory, 3));
processor.processOrders();
}
}
# 反例
不使用命令模式时,直接调用接收者方法:
public class WithoutCommandPattern {
public static void main(String[] args) {
PhoneInventory inventory = new PhoneInventory();
inventory.buyPhones(5);
inventory.sellPhones(3);
}
}
缺陷说明:
1.紧耦合:调用方直接依赖PhoneInventory
的具体方法,若方法名或参数变更(如buyPhones
改为purchasePhones
),所有调用代码需修改。
2.扩展困难:新增returnPhones
功能时,必须修改客户端代码调用新方法,违反开闭原则。
3.无法撤销:需手动记录操作历史并反向调用(如销售3台后需再采购3台),维护成本高。
4.缺乏灵活性:无法实现命令队列、延迟执行或事务管理,所有操作立即执行且无法批量控制。
# 原理
命令模式通过Command
接口定义执行和撤销方法,将操作封装为对象。调用者(如OrderProcessor
)维护命令队列,通过execute()
触发操作,undo()
实现回滚。接收者(如PhoneInventory
)负责具体业务逻辑,与调用者解耦。
# 缺点
1.类膨胀:每个操作需对应一个具体命令类,增加系统复杂度。
2.间接层过多:需多层级对象协作(命令对象、接收者、调用者),可能降低运行效率。
3.学习成本:开发者需理解命令封装与解耦机制,初期理解难度较高。
总结
命令模式通过封装请求为对象,实现发送者与接收者的彻底解耦,支持撤销、队列、组合命令等高级功能。适用于需要灵活控制操作流程的场景(如事务管理、操作历史回滚)。反观直接调用方式,虽简单高效,但难以应对复杂需求变更和扩展。选择时需权衡功能需求与系统复杂度。

微信公众号

QQ交流群
如若发现错误,诚心感谢反馈。
愿你倾心相念,愿你学有所成。
愿你朝华相顾,愿你前程似锦。