TypeScript设计模式之备忘录、命令(2)

抽象个Command, Command需要做到执行命令、撤消上次所做的操作及重做, 这里就可以用上面的UndoRedoManager:

abstract class Command implements Executable, UndoRedoable{ constructor(protected controller: Controllable) { } execute(param: {}){ UndoRedoManager.push(this, param); } redo(){ UndoRedoManager.redo(); } undo(){ UndoRedoManager.undo(); } }

接下来分别实现具体的 开、关、换台命令:

class OpenCommand extends Command{ execute(param: any){ super.execute(param); this.tv.open(); } undo(currParam: any, lastParam: any){ this.tv.close(); } } class CloseCommand extends Command{ execute(param: any){ super.execute(param); this.tv.close(); } undo(currParam: any, lastParam: any){ this.tv.open(); } } class SwitchCommand extends Command{ execute(param: any){ super.execute(param); this.tv.switchTo(param.channelNum); } undo(currParam: any, lastParam: any){ this.tv.switchTo(lastParam.channelNum); } }

最后来实现 电视和遥控器,遥控器通常只有一个开关按钮,要么开要么关,另外遥控器可以撤消到上次选的频道,也可以取消撤消,重新回到当前的:
电视只需要做具体的事就可以了,遥控器也不需要知道命令是谁在执行,只管发命令就好,这就是命令模式的好处。

class TV implements Controllable{ open(){ console.log('open'); } close(){ console.log('close'); } switchTo(channelNum: number){ console.log(`switch to channel: ${channelNum}`); } } class Controller { isOn: boolean = false; constructor(private openCmd: Command, private closeCmd: Command, private switchCmd: Command){ } onOff(){ if(this.isOn){ this.isOn = false; this.closeCmd.execute(null); } else { this.isOn = true; this.openCmd.execute(null); } } switchTo(channelNum: number){ this.switchCmd.execute({channelNum: channelNum}); } undo(){ UndoRedoManager.instance.undo(); //只需要调用UndoRedoManager做undo/redo就可以了,不需要管具体的细节 } redo(){ UndoRedoManager.instance.redo(); } }

来看看成果:
先定个执行顺序,
打开电视 -> 3频道 -> 4频道 -> 7频道 -> 撤消 -> 撤消 -> 重做 -> 11频道 -> 12频道 -> 撤消 -> 撤消 -> 关电视

预期结果:
open -> 3 -> 4 -> 7 -> 4 -> 3 -> 4 -> 11 -> 12 -> 11 -> 4 -> close
从11回到4是因为在push 11频道时的command是4,也就是7已经被删掉了。

看看具体执行结果:

let tv = new TV(); let controller = new Controller(new OpenCommand(tv), new CloseCommand(tv), new SwitchCommand(tv)); controller.onOff(); controller.switchTo(3); controller.switchTo(4); controller.switchTo(7); controller.undo(); controller.undo(); controller.redo(); controller.switchTo(11); controller.switchTo(12); controller.undo(); controller.undo(); controller.onOff();

执行结果:
open
switch to channel: 3
switch to channel: 4
switch to channel: 7
switch to channel: 4
switch to channel: 3
switch to channel: 4
switch to channel: 11
switch to channel: 12
switch to channel: 11
switch to channel: 4
close

完全一样,没问题。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/16a3df467d48ef99805f0a52fd8987ab.html