23种设计模式之【命令模式模式】-核心原理与 Java 实践
文章目录
- 命令模式(Command Pattern)
- 核心原理
- Java 实践示例
- 运行结果
- 命令模式的核心价值
- 命令模式在 GUI 操作、事务管理、任务调度等场景中应用广泛,例如:
命令模式(Command Pattern)
命令模式是 23 种设计模式中的一种行为型模式,其核心思想是将请求封装为一个对象(命令),从而使你可以用不同的请求对客户进行参数化,并且支持请求的排队、记录日志、撤销等操作。
核心原理
命令接口(Command):
声明执行操作的方法(通常是execute())
可选地声明撤销操作的方法(undo())
具体命令(ConcreteCommand):
实现命令接口,持有接收者(Receiver)的引用
在execute()方法中调用接收者的具体操作
若支持撤销,需在undo()中实现反向操作
接收者(Receiver):
知道如何执行与请求相关的操作,是实际业务逻辑的执行者
与命令解耦,不关心命令的存在
调用者(Invoker):
持有命令对象,负责触发命令的执行
不关心命令的具体实现和接收者是谁
客户端(Client):
创建具体命令对象,并设置其接收者
决定哪个命令与哪个接收者关联
命令模式的核心是 “封装请求”,将发出请求的责任和执行请求的责任分割开,通过命令对象连接两者。
Java 实践示例
下面以 “遥控器控制家电” 为例实现命令模式:
遥控器(调用者)可执行各种命令(开 / 关灯光、开 / 关电视)
支持命令的执行和撤销操作
package com.example.demo;public class CommandPattern {public static void main(String[] args) {// 创建接收者(家电)Light livingRoomLight = new Light("客厅");TV livingRoomTV = new TV("客厅");// 创建命令Command lightOn = new LightOnCommand(livingRoomLight);Command lightOff = new LightOffCommand(livingRoomLight);Command tvOn = new TVOnCommand(livingRoomTV);Command tvOff = new TVOffCommand(livingRoomTV);// 创建调用者(遥控器)RemoteControl remote = new RemoteControl();// 执行命令System.out.println("--- 执行命令 ---");remote.setCommand(lightOn);remote.pressButton();remote.setCommand(tvOn);remote.pressButton();// 撤销命令System.out.println("\n--- 撤销命令 ---");remote.pressUndoButton();remote.pressUndoButton();// 再次执行关闭命令System.out.println("\n--- 执行关闭命令 ---");remote.setCommand(lightOff);remote.pressButton();}public interface Command {void execute();void undo();}// 灯光接收者public static class Light {private String location;private boolean isOn;public Light(String location) {this.location = location;}public void on() {isOn = true;System.out.println(location + "灯光已打开");}public void off() {isOn = false;System.out.println(location + "灯光已关闭");}}// 电视接收者public static class TV {private String location;private boolean isOn;public TV(String location) {this.location = location;}public void on() {isOn = true;System.out.println(location + "电视已打开");}public void off() {isOn = false;System.out.println(location + "电视已关闭");}}// 开灯命令public static class LightOnCommand implements Command {private Light light;public LightOnCommand(Light light) {this.light = light;}@Overridepublic void execute() {light.on();}@Overridepublic void undo() {light.off();}}// 关灯命令(其他命令类似)public static class LightOffCommand implements Command {private Light light;public LightOffCommand(Light light) {this.light = light;}// 实现代码类似,execute()调用light.off(),undo()调用light.on()@Overridepublic void execute() {light.off();}@Overridepublic void undo() {light.on();}}public static class TVOnCommand implements Command {// 持有电视接收者的引用private TV tv;// 通过构造函数注入接收者public TVOnCommand(TV tv) {this.tv = tv;}// 执行命令:调用电视的打开方法@Overridepublic void execute() {tv.on();}// 撤销命令:对应的反向操作是关闭电视@Overridepublic void undo() {tv.off();}}public static class TVOffCommand implements Command {// 持有电视接收者的引用,通过构造函数注入private TV tv;public TVOffCommand(TV tv) {this.tv = tv;}// 执行命令:调用电视的关闭方法@Overridepublic void execute() {tv.off();}// 撤销命令:对应的反向操作是打开电视@Overridepublic void undo() {tv.on();}}public static class RemoteControl {private Command command;private Command lastCommand; // 用于撤销操作public void setCommand(Command command) {this.command = command;}// 执行命令public void pressButton() {command.execute();lastCommand = command; // 记录最后执行的命令}// 撤销命令public void pressUndoButton() {if (lastCommand != null) {lastCommand.undo();}}}
}
运行结果
— 执行命令 —
客厅灯光已打开
客厅电视已打开
— 撤销命令 —
客厅电视已关闭
客厅灯光已关闭
— 执行关闭命令 —
客厅灯光已关闭
命令模式的核心价值
解耦发送者和接收者:调用者无需知道接收者是谁以及如何执行操作
支持命令队列和批处理:可以将多个命令组合成宏命令一次性执行
支持撤销和重做:通过记录命令历史实现操作回滚
支持日志记录:可以记录命令执行日志,用于审计或故障恢复
命令模式在 GUI 操作、事务管理、任务调度等场景中应用广泛,例如:
文本编辑器的撤销 / 重做功能
数据库事务的提交 / 回滚
任务调度框架中的任务封装
遥控器、菜单等交互组件的命令封装