- 命令模式将动作的请求者从动作的执行者对象中解耦
请求者=>遥控器
接受者=> 各个厂商的类
把请求封装成一个特定的对象,打开电灯=>客厅电灯对象
遥控器的代码尽量保持简单,而把家电自动化的工作和进行该工作的对象一起封装在命令对象中
顾客
invoker(调用者)setCommand createCommandObject
command(命令)excute
receiver(执行者)
女招待 invoker
厨师 receiver
orderUp excute
订单 command
takeOrder setCommand
顾客 client
自下而上的建造一些东西,可能会有帮助
定义
将“请求”封装成对象,以便使用不同的请求、队列、或者日志、来参数化其他对象。命令模式也支持可撤销的操作
demo.js
let {LightOnCommand,LightOffCommand,Light}=require('./4.1.js')
let {GarageDoor,GarageDoorOpenCommand,GarageDoorCloseCommand}=require('./4.2.js')
let {Stereo,StereoOnWidthCDCommand,StereoOffWidthCDCommand} =require('./4.3.js')
let {NoCommand}=require('./4.4.js')
let {CeilingFanHighCommand,CeilingFanMediumCommand,CeilingFanLowCommand,CeilingFanOffCommand,CeilingFan}=require('./4.5.js')
let {MacroCommand}=require('./4.6.js')
class RemoteControlWithUndo{
constructor(){
this.onCommands=[]
this.offCommands=[]
this.undoCommand=null
// this.receiveres=[]
let noCommand=new NoCommand()
for(var i=0;i<7;i++){
this.onCommands[i]=noCommand
this.offCommands[i]=noCommand
}
this.undoCommand=noCommand
}
setCommand(index,onCommand,offCommand){
this.onCommands[index]=onCommand
this.offCommands[index]=offCommand
}
onButtonWasPushed(index){
this.onCommands[index].excute()
this.undoCommand=this.onCommands[index]
}
offButtonWasPushed(index){
this.offCommands[index].excute()
this.undoCommand=this.offCommands[index]
}
undoButtonWasPushed(){
this.undoCommand.undo()
}
}
class RemoteLoader{
constructor(){
let remoteControl=new RemoteControlWithUndo()
//将所有的装置创建在合适的位置
let livingRoomLight=new Light('Living Room')//卧室灯
let kitchenRoomLight=new Light('Kitchen Room')//厨房灯
let garageDoor=new GarageDoor()//车库门
let stereo=new Stereo()//CD
let ceilingFan=new CeilingFan()
//创建所有的电灯对象
let livingRoomLightOn=new LightOnCommand(livingRoomLight)
let livingRoomLightOff=new LightOffCommand(livingRoomLight)
let kitchenRoomLightOn=new LightOnCommand(kitchenRoomLight)
let kitchenRoomLightOff=new LightOffCommand(kitchenRoomLight)
//创建车库门开关的命令
let garageDoorOpenCommand=new GarageDoorOpenCommand(garageDoor)
let garageDoorCloseCommand=new GarageDoorCloseCommand(garageDoor)
//创建音响的开关命令
let stereoOnWithCDCommand=new StereoOnWidthCDCommand(stereo)
let stereoOffWidthCDCommand=new StereoOffWidthCDCommand(stereo)
//吊扇
let ceilingFanHighCommand=new CeilingFanHighCommand(ceilingFan)
let ceilingFanMediumCommand=new CeilingFanMediumCommand(ceilingFan)
let ceilingFanLowCommand=new CeilingFanLowCommand(ceilingFan)
let ceilingFanOffCommand=new CeilingFanOffCommand(ceilingFan)
remoteControl.setCommand(0,livingRoomLightOn,livingRoomLightOff)
remoteControl.setCommand(1,kitchenRoomLightOn,kitchenRoomLightOff)
remoteControl.setCommand(2,garageDoorOpenCommand,garageDoorCloseCommand)
remoteControl.setCommand(3,stereoOnWithCDCommand,stereoOffWidthCDCommand)
remoteControl.setCommand(4,ceilingFanHighCommand,ceilingFanOffCommand)
remoteControl.setCommand(5,ceilingFanMediumCommand,ceilingFanOffCommand)
remoteControl.setCommand(6,ceilingFanLowCommand,ceilingFanOffCommand)
//测试开关
// remoteControl.onButtonWasPushed(0)
// remoteControl.offButtonWasPushed(0)
// remoteControl.onButtonWasPushed(1)
// remoteControl.offButtonWasPushed(1)
// remoteControl.onButtonWasPushed(2)
// remoteControl.offButtonWasPushed(2)
// remoteControl.onButtonWasPushed(3)
// remoteControl.offButtonWasPushed(3)
//测试撤销操作
// remoteControl.onButtonWasPushed(5)
// remoteControl.onButtonWasPushed(6)
// remoteControl.offButtonWasPushed(6)
// remoteControl.undoButtonWasPushed()
// remoteControl.offButtonWasPushed(0)
// remoteControl.onButtonWasPushed(0)
// remoteControl.undoButtonWasPushed()
//测试宏命令(同时执行多个操作)
let onCommands=[livingRoomLightOn,kitchenRoomLightOn,stereoOnWithCDCommand]
let offCommands=[livingRoomLightOff,kitchenRoomLightOff,stereoOffWidthCDCommand]
let partyOnMacro=new MacroCommand(onCommands)
let partyOffMacro=new MacroCommand(offCommands)
remoteControl.setCommand(7,partyOnMacro,partyOffMacro)
remoteControl.onButtonWasPushed(7)
remoteControl.offButtonWasPushed(7)
remoteControl.undoButtonWasPushed()
}
}
new RemoteLoader()
1.js
//创建命令对象
class Command{
constructor(receiver){
this.receiver=receiver
}
excute(){
this.receiver.excute()
}
undo(){
console.log('撤销操作')
}
}
// 具体命令打开电灯
class LightOnCommand extends Command{
constructor(receiver){
super(receiver)
}
excute(){
console.log('我执行了开电灯command')
this.receiver.lightOn()
}
}
// 具体命令打开电灯
class LightOffCommand extends Command{
constructor(receiver){
super(receiver)
}
excute(){
console.log('我执行了关闭电灯command')
this.receiver.lightOff()
}
}
//receiver
class Light{
constructor(type){
this.type=type || 'living room'
// console.log('我是电灯receiver')
}
lightOn(){
console.log(this.type+'电灯已经被打开了')
}
lightOff(){
console.log(this.type+'电灯关闭')
}
}
module.exports={
LightOnCommand,
LightOffCommand,
Light
}
2.js
//创建命令对象
class Command{
constructor(receiver){
this.receiver=receiver
}
excute(){
this.receiver.excute()
}
undo(){
console.log('撤销操作')
}
}
//打开车库门
class GarageDoorOpenCommand{
constructor(receiver){
this.receiver=receiver
}
excute(){
console.log('我执行打开车库门的操作')
this.receiver.up()
}
}
//打开车库门
class GarageDoorCloseCommand{
constructor(receiver){
this.receiver=receiver
}
excute(){
console.log('我执行关闭车库门的操作')
this.receiver.down()
}
}
//receiver
class GarageDoor{
constructor(){
}
up(){
console.log('车库门打开')
}
down(){
console.log('车库门被关闭')
}
stop(){
console.log('车库门停止某个操作')
}
lightOn(){
console.log('车库电灯打开')
}
lightOff(){
console.log('车库电灯关闭')
}
}
module.exports={
GarageDoor,
GarageDoorOpenCommand,
GarageDoorCloseCommand
}
3.js
//创建命令对象
class Command{
constructor(receiver){
this.receiver=receiver
}
excute(){
// this.receiver.excute()
}
undo(){
console.log('撤销操作')
}
}
class StereoOnWidthCDCommand extends Command{
constructor(receiver){
super(receiver)
}
excute(){
this.receiver.on()
this.receiver.setCD()
this.receiver.setVolume(11)
}
}
class StereoOffWidthCDCommand extends Command{
constructor(receiver){
super(receiver)
}
excute(){
this.receiver.off()
}
}
class Stereo{
constructor(){
}
on(){
console.log('打开CD')
}
off(){
console.log('关闭CD')
}
setCD(){
console.log('播放CD')
}
setVolume(num){
console.log('调节播放声音到'+num)
}
}
module.exports={
Stereo,
StereoOnWidthCDCommand,
StereoOffWidthCDCommand
}
4.js
//创建命令对象
class Command{
constructor(receiver){
this.receiver=receiver
}
excute(){
this.receiver.excute()
}
undo(){
console.log('撤销操作')
}
}
class NoCommand extends Command{
constructor(){
super()
}
excute(){
console.log('不执行任何操作')
}
}
class NoReceiver{
}
module.exports={
NoCommand,
NoReceiver
}
5.js
//创建命令对象
class Command{
constructor(receiver){
this.receiver=receiver
}
excute(){
this.receiver.excute()
}
undo(){
console.log('撤销操作')
}
}
class CeilingFanCommand extends Command{
constructor(receiver){
super(receiver)
this.prevSpeed=null
}
undo(){
console.log()
if(this.prevSpeed===this.receiver.HIGH){
this.receiver.high()
}else if(this.prevSpeed===this.receiver.MEDIUM){
this.receiver.medium()
}else if(this.prevSpeed===this.receiver.LOW){
this.receiver.low()
}else if(this.prevSpeed===this.receiver.OFF){
this.receiver.off()
}
console.log('撤销到'+this.receiver.getSpeed())
}
}
class CeilingFanHighCommand extends CeilingFanCommand{
constructor(receiver){
super(receiver)
}
excute(){
console.log('执行高档')
this.prevSpeed=this.receiver.getSpeed()
this.receiver.high()
}
}
class CeilingFanMediumCommand extends CeilingFanCommand{
constructor(receiver){
super(receiver)
}
excute(){
console.log('执行中档')
this.prevSpeed=this.receiver.getSpeed()
this.receiver.medium()
}
}
class CeilingFanLowCommand extends CeilingFanCommand{
constructor(receiver){
super(receiver)
}
excute(){
console.log('执行低档')
this.prevSpeed=this.receiver.getSpeed()
this.receiver.low()
}
}
class CeilingFanOffCommand extends CeilingFanCommand{
constructor(receiver){
super(receiver)
}
excute(){
console.log('关闭操作'+this.receiver.getSpeed())
this.prevSpeed=this.receiver.getSpeed()
this.receiver.off()
}
}
//吊扇的类
class CeilingFan{
constructor(location){
this.HIGH=3
this.MEDIUM=2
this.LOW=1
this.OFF=0
this.location=location
this.speed=this.OFF
}
high(){
this.speed=this.HIGH
}
medium(){
this.speed=this.MEDIUM
}
low(){
this.speed=this.LOW
}
off(){
this.speed=this.OFF
}
getSpeed(){
return this.speed
}
}
module.exports={CeilingFanHighCommand,CeilingFanMediumCommand,CeilingFanLowCommand,CeilingFanOffCommand,CeilingFan}
6.js
//创建命令对象
class Command{
constructor(receiver){
this.receiver=receiver
}
excute(){
this.receiver.excute()
}
undo(){
console.log('撤销操作')
}
}
class MacroCommand extends Command{
constructor(commands){
super()
this.commands=commands
}
excute(){
for(let i=0;i<this.commands.length;i++){
this.commands[i].excute()
}
}
undo(){
for(let i=0;i<this.commands.length;i++){
this.commands[i].undo()
}
}
}
module.exports={MacroCommand}
网友评论