https://mp.weixin.qq.com/s/gyB93m0wpCSI8YFwSxrhkw
https://www.yuque.com/wubinhp/uxiv5i/ozc2c5#DtfZS
命令模式的本质是对命令进行封装,将命令的发送者和接受者解耦。
常见形式
// 设置命令const setCommand = (button, command) => {button.onclick = () => {command.execute();};};// 业务逻辑const MenuBar = {refresh: () => {console.log("refresh");},};const RefreshMenuBarCommand = (receiver) => {return {execute: () => {receiver.refresh();},};};const refreshMenuBarCommand = RefreshMenuBarCommand(MenuBar);// 绑定按钮和命令setCommand(refreshBtn, refreshMenuBarCommand);
JS的简单用法
const setCommand = (button, command) => {button.onclick = () => {command.execute();};};// 业务逻辑const MenuBar = {refresh: () => {console.log("refresh");},};setCommand(refreshBtn, MenuBar.refresh);
js 将函数作为一等公民,运算逻辑不一定要封装在 command.execute方法中然后传递 command对象,可以直接将函数进行传递。
引入undo/redo
实现数字的加减和undo/redo
<!DOCTYPE html><html lang="en"><body><button id="add">add</button><button id="del">del</button><button id="undo">undo</button><button id="redo">redo</button><!-- <script src="./command.js"></script>--><script>let num = 0;const addCommand = {execute: () => {num++;console.log("+:", num);},undo: () => {num--;console.log("undo:", num);},};const delCommand = {execute: () => {num--;console.log("-:", num);},undo: () => {num++;console.log("undo:", num);},};const commandManager = {undoStack: [],redoStack: [],executeCommand(command) {this.redoStack = [];this.undoStack.push(command);command.execute();},undo() {if (this.undoStack.length === 0) return;const lastCommand = this.undoStack.pop();lastCommand.undo();this.redoStack.push(lastCommand);},redo() {if (this.redoStack.length === 0) return;const lastCommand = this.redoStack.pop();lastCommand.execute();this.undoStack.push(lastCommand);},};const setCommand = (button, command) => {if (typeof command === "object") {button.onclick = function () {commandManager.executeCommand(command);};} else {button.onclick = function () {command.call(commandManager);};}};const addBtn = document.getElementById("add");const delBtn = document.getElementById("del");const undoBtn = document.getElementById("undo");const redoBtn = document.getElementById("redo");setCommand(addBtn, addCommand);setCommand(delBtn, delCommand);setCommand(undoBtn, commandManager.undo);setCommand(redoBtn, commandManager.redo);</script></body></html>
