请仔细阅读下面代码,理解其中的设计理念。

command.jpg

command-client.jpg
命令模式
命令模式: 命令模式是一中封装方法调用的方式,用来将行为请求者和行为实现者解除耦合。
实际场景
在软件系统中,行为请求者与行为实现者通常是一种紧耦合的关系,但某些场合,比如需要对行为进行记录、撤销或重做、事务等处理时,这种无法抵御变化的紧耦合的设计就不太合适。
命令模式的结构
- Client 客户
- Invoker 调用命令的对象
- Command 具体的命令
- Receiver 真正的命令执行对象
命令模式的例子
龟兔赛跑:
- 喜欢偷懒的兔子每个阶段移动0-60米
- 持之以恒的乌龟每个阶段移动10-50米
- 可以向右或者向左移动
- 每个阶段可以回滚
- 输出移动日志
- 支持添加更多参赛者
套用命令模式的结构,我们得到
Command: 向右移动(支持取消操作)、 向左移动(支持取消操作)...
Receiver: 兔子、乌龟、...
定义基本类型
/* command-interface.ts */
// 命令接口
export interface ICommand {
execute: (step: number) => any
undo: () => any
}
/* target-interface.ts */
// 参赛队员接口
export interface ITarget {
name: string
position: number
}
/* receiver-interface.ts */
// 接收者接口
export interface IRightReceiver {
moveRight: (step: number) => any;
rightUndo: () => any;
}
export interface ILeftReceiver {
moveLeft: (step: number) => any;
leftUndo: () => any;
}
/* command-class.ts */
// 命令类型
export enum CommandClass {
GO_RIGHT = 'GO_RIGHT',
GO_LEFT = 'GO_LEFT',
}
移动命令类
/* left-command.ts */
// 向左移动类
import { ILeftReceiver } from '../receiver-models/receiver-interface';
import { ICommand } from './command-interface';
export class LeftCommand implements ICommand {
protected receivers: ILeftReceiver[] = [];
public addReceiver (receiver: ILeftReceiver) {
this.receivers.push(receiver);
return this;
}
public removeReceiver (receiver: ILeftReceiver) {
const index = this.receivers.findIndex(item => item === receiver);
if (index !== -1) {
this.receivers.splice(index, 1);
}
}
public execute (step: number) {
this.receivers.map((receiver: ILeftReceiver) => {
receiver.moveLeft(step);
});
}
public undo () {
this.receivers.map((receiver: ILeftReceiver) => {
receiver.leftUndo();
});
}
}
/* right-command.ts */
// 向右移动类
import { IRightReceiver } from '../receiver-models/receiver-interface';
import { ICommand } from './command-interface';
export class RightCommand implements ICommand {
protected receivers: IRightReceiver[] = [];
public addReceiver (receiver: IRightReceiver) {
this.receivers.push(receiver);
return this;
}
public removeReceiver (receiver: IRightReceiver) {
const index = this.receivers.findIndex(item => item === receiver);
if (index !== -1) {
this.receivers.splice(index, 1);
}
}
public execute (step: number) {
this.receivers.map((receiver: IRightReceiver) => {
receiver.moveRight