设计模式之------命令模式

‌一、命令模式定义与核心思想‌

‌命令模式(Command Pattern) ‌ 是一种行为型设计模式,其核心是将‌请求 ‌或‌操作‌封装为独立对象,实现调用者(发送请求)与接收者(执行操作)的解耦。通过这种方式,可以灵活管理请求的队列化、撤销、重做等复杂逻辑‌。

  • ‌核心思想‌:将"动作"抽象为可传递、存储的对象,使得操作本身具备独立性和可扩展性‌。

‌二、命令模式的结构组成‌

‌角色‌ ‌作用‌
‌Command‌ 抽象命令接口,声明执行方法(如 execute())‌。
‌ConcreteCommand‌ 具体命令类,绑定接收者并实现操作细节(如复制、粘贴命令)‌。
‌Receiver‌ 实际操作执行者(如编辑器、DOM元素)‌。
‌Invoker‌ 调用者,触发命令执行(如按钮、任务调度器)‌。

‌三、应用场景与意义‌

‌1. 典型应用场景‌
  • ‌需要支持撤销/重做‌:例如文本编辑器的操作历史记录‌47。
  • ‌多步骤任务管理‌:如批量表单提交、动画序列执行‌46。
  • ‌复杂交互解耦‌:按钮点击触发不同业务逻辑,避免代码冗余‌57。
‌2. 核心意义‌
  • ‌解耦调用与执行‌:发送者无需关注接收者的具体实现‌。
  • ‌灵活扩展性‌:新增命令无需修改现有代码(符合开闭原则)‌。
  • ‌操作管理能力‌:支持队列化、日志记录、事务处理等高级功能‌。

‌四、由浅入深的三层案例‌

‌1. 基础示例:按钮触发命令‌
javascript 复制代码
// 命令接口
class Command {
  execute() {}
}

// 具体命令:切换主题
class ToggleThemeCommand extends Command {
  constructor(receiver) {
    super();
    this.receiver = receiver; // Receiver为DOM元素
  }
  execute() {
    this.receiver.classList.toggle('dark-mode');
  }
}

// 调用者:按钮绑定命令
const button = document.getElementById('theme-btn');
button.onclick = new ToggleThemeCommand(document.body).execute;

‌关键点‌:按钮(Invoker)与DOM操作(Receiver)解耦,支持动态替换命令‌。


‌2. 进阶示例:支持撤销的操作历史‌
kotlin 复制代码
class HistoryManager {
  constructor() {
    this.stack = [];
  }
  push(command) {
    this.stack.push(command);
  }
  undo() {
    const command = this.stack.pop();
    command?.undo(); // 命令需实现undo方法
  }
}

// 具体命令:文本输入(支持撤销)
class TextInputCommand {
  constructor(editor, newText) {
    this.editor = editor;
    this.prevText = editor.textContent;
    this.newText = newText;
  }
  execute() {
    this.editor.textContent = this.newText;
  }
  undo() {
    this.editor.textContent = this.prevText;
  }
}

// 使用示例
const editor = document.getElementById('editor');
const history = new HistoryManager();
history.push(new TextInputCommand(editor, 'Hello World'));
history.undo(); // 恢复为原始文本

‌关键点‌:通过命令对象记录操作状态,实现撤销功能‌。


‌3. 高阶示例:动画队列调度‌
javascript 复制代码
class AnimationQueue {
  constructor() {
    this.queue = [];
  }
  addCommand(command) {
    this.queue.push(command);
  }
  run() {
    this.queue.reduce((prev, cmd) => 
      prev.then(() => cmd.execute()), Promise.resolve()
    );
  }
}

// 具体命令:DOM元素动画
class MoveCommand {
  constructor(element, x, y) {
    this.element = element;
    this.x = x;
    this.y = y;
  }
  execute() {
    return new Promise(resolve => {
      this.element.style.transform = `translate(${this.x}px, ${this.y}px)`;
      this.element.addEventListener('transitionend', resolve);
    });
  }
}

// 使用示例
const box = document.getElementById('box');
const queue = new AnimationQueue();
queue.addCommand(new MoveCommand(box, 100, 0));
queue.addCommand(new MoveCommand(box, 100, 100));
queue.run(); // 顺序执行动画

‌关键点‌:通过命令队列管理异步操作,实现复杂动画序列‌。


命令模式通过将‌操作对象化‌,解决了前端开发中调用与执行的强耦合问题,适用于需要动态管理、扩展或记录用户交互的场景。从简单的按钮绑定到复杂的任务队列,其分层设计思想能够显著提升代码的可维护性和灵活性‌。

相关推荐
鬼手点金5 小时前
nanoGPT/nanochat 能做出 DeepSeek/Qwen 这样的大模型吗?
服务器·前端·javascript·bug·openclaw
软件技术NINI5 小时前
美妆商城html+Css+js 4页
javascript·css·html
蛋蛋的就会顺顺的5 小时前
hot100 p0——栈,贪心算法,动态规划
java·前端·javascript·算法·leetcode·力扣
程序员Sunday5 小时前
TypeScript 的 any、unknown、never 有什么区别?
前端·面试·typescript
朱涛的自习室5 小时前
70 美金的 Beyond Compare,我让 Gemini 4 和 DeepSeek 造个开源免费版(Day 2)
android·前端·人工智能
小 黄 鸡6 小时前
HashMap 面试必会知识点详解(JDK 8)
java·面试·职场和发展
码艺-Alimjan6 小时前
Tauri 源码备份 · 打包 & 解压 总结,源码收集之路
前端·javascript·vue.js
小马不起床6 小时前
零基础玩转 FastAPI_11:前端后台管理页面
前端·状态模式·fastapi
子非鱼a7 小时前
【文件上传】一个普普通通的edu16
前端
美狐美颜SDK开放平台8 小时前
直播APP如何实现美白滤镜功能?视频美颜SDK技术开发方案详解
前端·数据库·人工智能·音视频·美颜sdk·直播美颜sdk·视频美颜sdk