Command
Turn a request into a stand-alone object that can be queued, logged or undone.
Use it when
You need undo/redo, job queues or to parameterise objects with operations.
// Command
interface ICommand {
execute(): void;
}
class DocumentReceiver {
public open(): void {
console.log("Doc Receiver - Open");
}
public read(): void {
console.log("Doc Receiver - Read");
}
public save(): void {
console.log("Doc Receiver - Save");
}
}
class SaveCommand implements ICommand {
private docReceiver: DocumentReceiver;
constructor(docRec: DocumentReceiver) {
this.docReceiver = docRec;
}
public execute(): void {
console.log("Command - Save");
this.docReceiver.save();
}
}
class OpenCommand implements ICommand {
private docReceiver: DocumentReceiver;
constructor(docRec: DocumentReceiver) {
this.docReceiver = docRec;
}
public execute(): void {
console.log("Command - Open");
this.docReceiver.open();
}
}
class DocumentInvoker {
private _commands: { [id: string]: ICommand };
private _history: [number, string][];
constructor() {
this._commands = {};
this._history = [];
}
registerCommand(commandName: string, command: ICommand): void {
this._commands[commandName] = command;
}
showHistory(): void {
this._history.forEach((row) => {
console.log("Row "+ row[0] +" => " + row[1] );
})
}
execute(commandName: string): void {
if (commandName in this._commands) {
this._commands[commandName].execute();
this._history.push([Date.now(), commandName]);
} else {
console.log("Command name " + commandName + " not recognised)
}
}
replayLast(numberOfCommands: number): void {
const command = this._history.slice(
this._history.length - numberOfCommands,
this._history.length
)
command.forEach((cmd) => {
this._commands[cmd[1]].execute();
})
}
}
const clientCode = () => {
const rec = new DocumentReceiver();
const open = new OpenCommand(rec);
const save = new SaveCommand(rec);
const invoker = new DocumentInvoker();
invoker.registerCommand("OPEN", open);
invoker.registerCommand("SAVE", save);
invoker.execute("OPEN");
invoker.execute("SAVE");
invoker.execute("OPEN");
invoker.execute("SAVE");
invoker.execute("SAVE11");
invoker.showHistory();
invoker.replayLast(1);
}