1. 程式人生 > >ES6設計模式之命令模式篇

ES6設計模式之命令模式篇

模式的本質是將物件的行為和物件的呼叫者解耦。和策略模式不同的是將物件和物件的行為解耦。對於呼叫這來說只是執行excute方法就行了。這裡需要注意三部分,命令物件,呼叫者物件,被呼叫物件。 命令模式將"請求"封裝成物件,以便使用不同的請求,佇列,或者日誌來引數化其他物件。命令模式也支援撤銷操作。 程式碼如下

class Command {

constructor(){ }

execute(){ throw “nothing to execute”; }

}

//命令模式的只有一個執行方法對於呼叫這來說,只知道這行execute就可以了。

// 下面是一堆物件有各種不同的動作。

// 電燈物件

class ElectricLight{

constructor(name){

this.name = name; t

his.electricLight = “this is a light”;

}

on(){ console.log(open on light in ${this.name}); }

off(){ console.log(off light ${this.name}); }

}

// 風扇物件

class ElectricFan{

constructor(){ this.electricFan = “this is a fan”; }

openFan(){ console.log(“open the fan”); }

offFan(){ console.log(“power off the fan”); }

}

// 電冰箱物件

class Freeze{

constructor(){ this.freeze = “this is a freeze”; }

freezeOn(){ console.log(“make the freeze on”); }

freezeOff(){ console.log(“make the freeze off”); }

}

// 如上各個物件都有不同的命令物件。現在要這些命令整合到一起。

// 將上面的各種物件封裝到命令物件裡面。讓他們具有相同的函式名字。

class LinghtCommand extends Command{

constructor(name){ super(); this.name = name; this.electricLight = new ElectricLight(name); }

execute(){ this.electricLight.on(this.name); }

undo(){ this.electricLight.off(this.name); }

}

class ElectricFanCommand extends Command{

constructor(){ super(); this.electricFan = new ElectricFan(); this.name = “electricFan”; }

execute(){ this.electricFan.openFan(this.name); }

undo(){ this.electricFan.offFan(this.name); }

}

class FreezeCommand extends Command{

constructor(){ super(); this.freezeFan = new Freeze(); this.name = “freezeFan”; }

execute(){ this.freezeFan.freezeOn(this.name); }

undo(){ this.freezeFan.freezeOff(this.name); }

}

// 下面是呼叫者物件,也可以稱為控制器。

class SimpleControl{

constructor(){ this.commandObj = {}; this.lastCommand = “”; }

setCommand(command){ this.commandObj[command.name] = command; }

buttonPass(name){ if(this.commandObj[name]){ this.lastCommand = name; this.commandObj[name].execute(); }else{ console.log(“sorry ,there don’t have you command!”); } }

buttonUndo(){ this.commandObj[this.lastCommand].undo(); }

}

// 我認為書上面給的例子並不好,用0,1,2.代替不同的命令語義不夠清晰。

// 不能充分利用js語言靈活的有點,所以我應該做一下修改。

// 應該在setCommand傳入名字,執行的時候執行名字。強制要求每個命令都有名字,並且各不相同。

let control = new SimpleControl();

control.setCommand(new LinghtCommand(“live”));

control.setCommand(new LinghtCommand(“kitchen”));

control.setCommand(new ElectricFanCommand());

control.setCommand(new FreezeCommand());

control.buttonPass(“live”);

control.buttonPass(“freezeFan”);

control.buttonPass(“electricFan”);

control.buttonPass(“kitchen”);

control.buttonUndo();