简介
假设你有一个智能家居遥控器,上面有多个按钮,每个按钮对应不同的设备操作(如开灯、关灯、调空调温度)。
命令模式的解决方案是:
- 将每个操作(如“开灯”)封装成一个独立的命令对象,包含执行和撤销方法。
- 遥控器(调用者)不直接控制设备,而是通过触发命令对象来间接操作设备。
- 你可以灵活地为按钮更换命令,甚至实现“一键多操作”或“撤销”功能。
适用场景
- 需要将请求发送者与接收者解耦(如菜单项触发不同操作)。
- 支持请求的排队、撤销/重做、日志记录(如文本编辑器的撤销功能)。
- 需要支持宏命令(一键执行多个命令)。
优点
- 解耦请求发送者和接收者,增强扩展性。
- 支持撤销、重做、事务等复杂操作。
缺点
- 每个命令需单独实现类,增加代码量。
- 复杂命令可能引入多层嵌套逻辑。
类图
代码
// 命令接口interface Command {void execute();void undo();}// 接收者:灯class Light {public void on() {System.out.println("灯已打开");}public void off() {System.out.println("灯已关闭");}}// 具体命令:开灯class LightOnCommand implements Command {private Light light;public LightOnCommand(Light light) {this.light = light;}@Overridepublic void execute() {light.on();}@Overridepublic void undo() {light.off();}}// 调用者:遥控器按钮class RemoteControl {private Command command;public void setCommand(Command command) {this.command = command;}public void pressButton() {command.execute();}public void pressUndo() {command.undo();}}// 客户端public class CommandDemo {public static void main(String[] args) {Light light = new Light();Command lightOn = new LightOnCommand(light);RemoteControl remote = new RemoteControl();remote.setCommand(lightOn);remote.pressButton(); // 执行命令remote.pressUndo(); // 撤销命令}}
应用场景
数据库事务中的操作可通过命令模式实现,支持执行与回滚。
import java.util.Stack;// 事务命令接口interface TransactionCommand {void execute();void rollback();}// 接收者:数据库操作class Database {public void insert(String data) {System.out.println("插入数据: " + data);}public void delete(String data) {System.out.println("删除数据: " + data);}}// 具体命令:插入操作class InsertCommand implements TransactionCommand {private Database db;private String data;public InsertCommand(Database db, String data) {this.db = db;this.data = data;}@Overridepublic void execute() {db.insert(data);}@Overridepublic void rollback() {db.delete(data);}}// 事务管理器(支持回滚)class TransactionManager {private Stack<TransactionCommand> history = new Stack<>();public void submit(TransactionCommand command) {command.execute();history.push(command);}public void rollbackAll() {while (!history.isEmpty()) {history.pop().rollback();}}}// 客户端public class TransactionDemo {public static void main(String[] args) {Database db = new Database();TransactionManager manager = new TransactionManager();manager.submit(new InsertCommand(db, "A"));manager.submit(new InsertCommand(db, "B"));System.out.println("\n回滚事务:");manager.rollbackAll();}}