23种设计模式-命令(Command)设计模式
命令设计模式
- 🚩什么是命令设计模式?
- 🚩命令设计模式的特点
- 🚩命令设计模式的结构
- 🚩命令设计模式的优缺点
- 🚩命令设计模式的Java实现
- 🚩代码总结
- 🚩总结
🚩什么是命令设计模式?
命令设计模式(Command Pattern) 是一种 行为型设计模式,它将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。
使用场景
-
将请求调用者和请求接收者解耦
-
支持命令的撤销(Undo)和恢复(Redo)操作
-
支持事务系统 或 将一组操作组合成一个复合命令
-
支持宏命令(命令队列) 或 将命令存入日志
🚩命令设计模式的特点
-
解耦调用者和接收者:调用者无需知道接收者的具体实现
-
可扩展性强:可以方便地添加新的命令
-
支持撤销和重做:可以记录命令历史实现撤销/重做功能
-
支持事务:可以将一组命令组合成一个事务
-
灵活性高:命令可以被排队、记录日志或延迟执行
🚩命令设计模式的结构
命令模式主要包含以下部分:
-
Command(命令接口):声明执行操作的接口
-
ConcreteCommand(具体命令):将一个接收者对象绑定于一个动作,实现执行方法
-
Invoker(调用者):要求命令对象执行请求
-
Receiver(接收者):知道如何实施与执行一个请求相关的操作
-
Client(客户端):创建具体命令对象并设置其接收者
🚩命令设计模式的优缺点
✅ 优点
-
降低系统耦合度:调用者和接收者之间没有直接引用
-
扩展性好:新增命令不会影响现有代码
-
支持撤销/重做:可以方便地实现命令的撤销和恢复
-
支持事务:可以将一组命令组合成一个复合命令
-
灵活性高:可以方便地实现命令队列和日志请求
❌ 缺点
-
可能产生过多具体命令类:每个操作都需要一个具体命令类
-
增加系统复杂度:引入了额外的抽象层
-
性能开销:命令对象的创建和执行可能带来额外的开销
🚩命令设计模式的Java实现
代码地址:GitHub
- 创建
Receiver(接收者)
类
/**
* @author hanson.huang
* @version V1.0
* @ClassName Tv
* @Description 接收者 - 电视机
* @date 2025/3/25 16:42
**/
public class Tv {
public void onAction() {
System.out.println("电视机开机了...");
}
public void offAction() {
System.out.println("电视机关机了...");
}
}
- 创建
Command(命令接口)
/**
* @author hanson.huang
* @version V1.0
* @InterfaceName Command
* @Description 命令接口
* @date 2025/3/25 16:39
**/
public interface Command {// 命令接口
public void Execute();// 执行命令
}
-
创建具体命令类
- 开机命令
/** * @author hanson.huang * @version V1.0 * @ClassName OnCommand * @Description 开机命令 * @date 2025/3/25 16:42 **/ public class OnCommand implements Command { private Tv tv; public OnCommand(Tv tv) { this.tv = tv; } @Override public void Execute() { tv.onAction(); } }
- 关机命令
/** * @author hanson.huang * @version V1.0 * @ClassName OffCommand * @Description 关机命令 * @date 2025/3/25 16:43 **/ public class OffCommand implements Command { private Tv tv; public OffCommand(Tv tv) { this.tv = tv; } @Override public void Execute() { tv.offAction(); } }
-
创建
Invoker(调用者)
类
/**
* @author hanson.huang
* @version V1.0
* @ClassName Invoker
* @Description 请求者
* @date 2025/3/25 16:40
**/
public class Invoker { // 请求者
private Command command;// 命令
public void setCommand(Command command) { // 设置请求者 的 请求的命令
this.command = command;
}
public void call() { // 调用
command.Execute();
}
}
- 测试命令模式
/**
* @author hanson.huang
* @version V1.0
* @ClassName CommandPattern
* @Description 测试命令模式
* @date 2025/3/25 16:44
**/
public class CommandPattern {
public static void main(String[] args) {
Tv tv = new Tv(); // 接收者对象 - 电视机
Command onCommand = new OnCommand(tv); // 开机命令
Command offCommand = new OffCommand(tv); // 关机命令
Invoker invoker = new Invoker(); // 调用者
invoker.setCommand(onCommand); // 设置开机命令
invoker.call(); // 执行命令
System.out.println("=======================");
invoker.setCommand(offCommand); // 设置关机命令
invoker.call(); // 执行命令
}
}
📌 运行结果
🚩代码总结
-
Tv 作为接收者知道如何执行具体的操作
-
Command 接口定义了执行命令的统一方法
-
OnCommand 和 OffCommand 是具体命令类,绑定接收者和动作
-
Invoker 调用命令对象执行请求
-
CommandPattern 客户端创建命令对象并设置其接收者
🚩总结
-
命令设计模式 将请求封装为对象,使不同的请求、队列或日志成为可能
-
核心是 解耦请求发送者和接收者,使发送者无需知道接收者的具体实现
-
适用于 需要支持撤销/重做、事务、命令队列 等场景
✅ Java源码中的应用场景:
-
Swing/AWT中的事件处理:
-
java.awt.Action
和javax.swing.Action
-
按钮点击等事件处理
-
-
Java线程池:
-
java.lang.Runnable
接口类似于命令接口 -
线程池执行命令对象
-
-
Servlet过滤器链:
javax.servlet.Filter
接口定义命令模式
-
Spring框架:
-
org.springframework.core.command.Command
接口 -
Spring Batch中的任务执行
-
-
JUnit测试框架:
- 测试用例的执行采用命令模式
-
数据库事务:
- 一组SQL命令组成事务执行
创作不易,不妨点赞、收藏、关注支持一下,各位的支持就是我创作的最大动力❤️