JavaScript 语言设计模式 命令模式的撤销重做系统

JavaScript阿木 发布于 2025-06-25 10 次阅读


摘要:

命令模式是一种行为设计模式,它将请求封装为一个对象,从而允许用户对请求进行参数化、排队或记录请求,并支持可撤销的操作。本文将围绕JavaScript语言,探讨命令模式在撤销重做系统中的应用,并通过实际代码实现来展示如何构建一个简单的撤销重做功能。

一、

在软件开发中,撤销和重做功能是用户界面中常见的操作,尤其是在文本编辑器、图形设计软件等应用中。这些功能允许用户在执行操作后,可以撤销之前的操作,或者重新执行已经被撤销的操作。命令模式为这种功能提供了一种优雅的实现方式。

二、命令模式概述

命令模式是一种设计模式,它将请求封装为一个对象,从而允许用户对请求进行参数化、排队或记录请求,并支持可撤销的操作。命令模式的主要角色包括:

- 客户端(Client):发送请求的对象。

- 命令(Command):封装请求的对象。

- 接收者(Receiver):执行与请求相关的操作的对象。

- 调用者(Invoker):负责调用命令对象执行请求的对象。

三、撤销重做系统的设计

在撤销重做系统中,我们需要维护一个命令栈来记录用户执行的操作。每次用户执行一个操作时,我们创建一个命令对象并将其推入栈中。当用户请求撤销时,我们从栈中弹出命令对象并执行其撤销操作;当用户请求重做时,我们从栈中弹出命令对象并执行其重做操作。

四、JavaScript实现

以下是一个简单的JavaScript实现,展示了如何使用命令模式构建撤销重做系统。

javascript

// 命令接口


class Command {


execute() {}


undo() {}


}

// 文本编辑器接收者


class TextEditor {


constructor() {


this.text = '';


}

append(text) {


this.text += text;


}

remove(text) {


this.text = this.text.replace(text, '');


}

getText() {


return this.text;


}


}

// 具体命令:添加文本


class AppendCommand extends Command {


constructor(receiver, text) {


super();


this.receiver = receiver;


this.text = text;


}

execute() {


this.receiver.append(this.text);


}

undo() {


this.receiver.remove(this.text);


}


}

// 具体命令:删除文本


class RemoveCommand extends Command {


constructor(receiver, text) {


super();


this.receiver = receiver;


this.text = text;


}

execute() {


this.receiver.remove(this.text);


}

undo() {


this.receiver.append(this.text);


}


}

// 调用者


class Invoker {


constructor() {


this.commandStack = [];


}

storeCommand(command) {


this.commandStack.push(command);


}

undo() {


if (this.commandStack.length > 0) {


const command = this.commandStack.pop();


command.undo();


}


}

redo() {


// 实现重做功能,可能需要额外的数据结构来支持


}


}

// 客户端


const editor = new TextEditor();


const invoker = new Invoker();

const appendCommand = new AppendCommand(editor, 'Hello');


const removeCommand = new RemoveCommand(editor, 'Hello');

invoker.storeCommand(appendCommand);


invoker.storeCommand(removeCommand);

console.log(editor.getText()); // 输出:HelloHello

invoker.undo(); // 输出:Hello


invoker.undo(); // 输出:空字符串

invoker.redo(); // 输出:Hello


五、总结

本文通过JavaScript语言,展示了命令模式在撤销重做系统中的应用。通过定义命令接口和具体命令类,我们能够将操作封装成对象,并支持撤销和重做功能。这种设计模式使得代码更加模块化、可扩展,并且易于维护。

在实际应用中,可以根据具体需求对撤销重做系统进行扩展,例如添加更多类型的命令、支持重做功能、优化性能等。通过命令模式,我们可以轻松地实现复杂的功能,提高代码的可读性和可维护性。