Typescript 命令模式(Command)
阿新 • • 發佈:2020-12-08
請仔細閱讀下面程式碼,理解其中的設計理念。
command.jpgcommand-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(step);
}