《命令模式》PPT课件.ppt

上传人:牧羊曲112 文档编号:5481779 上传时间:2023-07-11 格式:PPT 页数:43 大小:1.59MB
返回 下载 相关 举报
《命令模式》PPT课件.ppt_第1页
第1页 / 共43页
《命令模式》PPT课件.ppt_第2页
第2页 / 共43页
《命令模式》PPT课件.ppt_第3页
第3页 / 共43页
《命令模式》PPT课件.ppt_第4页
第4页 / 共43页
《命令模式》PPT课件.ppt_第5页
第5页 / 共43页
点击查看更多>>
资源描述

《《命令模式》PPT课件.ppt》由会员分享,可在线阅读,更多相关《《命令模式》PPT课件.ppt(43页珍藏版)》请在三一办公上搜索。

1、1,第十一章 命令模式,家电自动化遥控器的API遥控器有七个可编程的插槽(每个控制一个不同的家电自动化装置),每个插槽有对应的开(on)/关(off)按钮;有一个撤消(undo)按钮。有一组Java类,这些类是由多家厂商开发出来的,用来控制家电装置,例如电灯、风扇、热水器、音响设备等。,2,遥控器,3,厂商类,喷头,立体声音响,水龙头,热水器,恒温器,厨具控制,4,家电自动化遥控器的API(续)目标:创建一组控制遥控器的API,每个插槽能控制一个或一组装置(包括目前的装置和未来可能的装置)。问题:有许多厂商类,每个类有各自的操作。遥控器应该怎样解读按钮被按下的动作?解决方法:采用“命令对象”封

2、装动作请求。当按钮按下时,请命令对象做相关的工作。让“动作的请求者(遥控器)”从“动作的执行者(厂商类之一的实例)”对象中解耦。,5,餐厅订餐,6,更详细地研究刚才的交互过程。,7,从餐厅到命令模式,与订餐过程的略微不同之处:客户一般不会直接指定厨师。,8,实现命令接口 所有的命令对象实现相同的包含一个方法的接口。在餐厅中,此方法为orderUp(),命令对象中惯用名称execute()。public interface Command public void execute();,只有这一个方法。,9,实现一个打开电灯的命令,根据厂商提供的类,light有两个方法:on()和off()。pu

3、blic class LightOnCommand implements Command Light light;public LightOnCommand(Light light)this.light=light;public void execute()light.on();,10,使用命令对象 假定遥控器只有一个按钮和对应的插槽:public class SimpleRemoteControl()Command slot;public SimpleRemoteControl()public void setCommand(Command command)slot=command;publ

4、ic void buttonWasPressed()slot.execute();,设置插槽控制的命令。如果要改变遥控器的行为,可以重复调用这个方法。,遥控器的角色是“调用者”。,11,遥控器使用的简单测试public class RemoteControlTest public class static void main(String args)SimpleRemoteControl remote=new SimpleRemoteControl();Light light=new Light();LightOnCommand lightOn=new LightOnCommand(light

5、);remote.setCommand(lightOn);remote.buttonWasPressed();,客户,调用者,创建一个命令对象,接收者,命令传给调用者,调用者执行命令,12,命令模式定义,利用命令来参数化对象。遥控器对象并不关心是什么命令对象,只要该命令对象实现了Command接口即可。命令模式也可以实现队列、日志和撤消操作。,13,命令模式类图,14,将命令指定到插槽 将遥控器的每个插槽,对应到一个命令,把遥控器变成“调用者”。当按下按钮,相应命令对象的execute()方法就会被调用,使得接收者的动作被调用。,15,16,实现遥控器public class RemoteCo

6、ntrol Command onCommands;Command offCommands;public RemoteControl()onCommands=new Command7;offCommands=new Command7;Command noCommand=new NoCommand();for(int i=0;i 7;i+)onCommandsi=noCommand;offCommandsi=noCommand;public void setCommand(int slot,Command onCommand,Command offCommand)onCommandsslot=on

7、Command;offCommandsslot=offCommand;,17,实现遥控器(续)public void onButtonWasPushed(int slot)onCommandsslot.execute();public void offButtonWasPushed(int slot)offCommandsslot.execute();public String toString()/覆盖toString(),打印出每个插槽和它对应的命令。StringBuffer stringBuff=new StringBuffer();stringBuff.append(n-Remote

8、Control-n);for(int i=0;i onCommands.length;i+)stringBuff.append(slot+i+onCommandsi.getClass().getName()+offCommandsi.getClass().getName()+n);return stringBuff.toString();,18,实现命令 LightOnCommand与前面的一样,LightOffCommand也是类似的。public class LightOffCommand implements Command Light light;public LightOffComm

9、and(Light light)this.light=light;public void execute()light.off();,19,实现命令(续)StereoOffCommand很简单,下面给出StereoOnWithCDCommand:public class StereoOnWithCDCommand implements Command Stereo stereo;public StereoOnWithCDCommand(Stereo stereo)this.stereo=stereo;public void execute()stereo.on();stereo.setCD()

10、;stereo.setVolume(11);,实现这个请求需要调用音响的三个方法:首先打开它,然后设置成播放CD,最后把音量设置成11。,20,测试遥控器public class RemoteLoader public static void main(String args)RemoteControl remoteControl=new RemoteControl();Light livingRoomLight=new Light(Living Room);Light kitchenLight=new Light(Kitchen);CeilingFan ceilingFan=new Ceil

11、ingFan(Living Room);GarageDoor garageDoor=new GarageDoor();Stereo stereo=new Stereo(Living Room);,所有装置创建在合适的位置。,客户,调用者,21,测试遥控器(续)LightOnCommand livingRoomLightOn=new LightOnCommand(livingRoomLight);LightOffCommand livingRoomLightOff=new LightOffCommand(livingRoomLight);LightOnCommand kitchenLightOn

12、=new LightOnCommand(kitchenLight);LightOffCommand kitchenLightOff=new LightOffCommand(kitchenLight);,创建所有电灯命令对象。,22,测试遥控器(续)CeilingFanOnCommand ceilingFanOn=new CeilingFanOnCommand(ceilingFan);CeilingFanOffCommand ceilingFanOff=new CeilingFanOffCommand(ceilingFan);GarageDoorUpCommand garageDoorUp=ne

13、w GarageDoorUpCommand(garageDoor);GarageDoorDownCommand garageDoorDown=new GarageDoorDownCommand(garageDoor);,创建掉扇开与关命令。,创建车库门上与下的命令。,23,测试遥控器(续)StereoOnWithCDCommand stereoOnWithCD=new StereoOnWithCDCommand(stereo);StereoOffCommand stereoOff=new StereoOffCommand(stereo);remoteControl.setCommand(0,l

14、ivingRoomLightOn,livingRoomLightOff);remoteControl.setCommand(1,kitchenLightOn,kitchenLightOff);remoteControl.setCommand(2,ceilingFanOn,ceilingFanOff);remoteControl.setCommand(3,stereoOnWithCD,stereoOff);,创建音响开与关命令。,所有命令加载到遥控器插槽中。,24,测试遥控器(续)System.out.println(remoteControl);remoteControl.onButtonWa

15、sPushed(0);remoteControl.offButtonWasPushed(0);remoteControl.onButtonWasPushed(1);remoteControl.offButtonWasPushed(1);remoteControl.onButtonWasPushed(2);remoteControl.offButtonWasPushed(2);remoteControl.onButtonWasPushed(3);remoteControl.offButtonWasPushed(3);,用toString()方法打印遥控器每个插槽指定的命令。,按下每个插槽开与关命

16、令。,25,测试结果,开启插槽,关闭插槽,命令执行结果,26,NoCommand对象 NoCommand对象是一个空对象(null object)。在遥控器中,我们不想每次都检查某个插槽是否加载了命令。我们将每个插糟都预先指定NoCommand对象,以便确定每个插槽永远都有命令对象。否则,需要类似下面的代码:public void onButtonWasPushed(int slot)if(onCommandsslot!=null)onCommandsslot.execute();,27,遥控器API,28,支持undo功能(以电灯为例)在Command接口中加入undo()方法。public

17、 interface Command public void execute();public void undo();从LightOnCommand开始下手。public class LightOnCommand implements CommandLight light;public LightOnCommand(Light light)this light=light;public void execute()Light.on();public void undo()light.off();,execute()打开电灯,undo()就是关闭电灯。,29,支持undo功能(以电灯为例)(续

18、)public class LightOffCommand implements CommandLight light;public LightOffCommand(Light light)this light=light;public void execute()Light.off();public void undo()light.on();,undo()把电灯打开。,30,支持undo功能(续)修改遥控器类。加入一个新的实例变量,追踪最后被调用的命令。public class RemoteControlWithUndo Command onCommands;Command offComm

19、ands;Command undoCommand;public RemoteControlWithUndo()onCommands=new Command7;offCommands=new Command7;Command noCommand=new NoCommand();for(int i=0;i7;i+)onCommandsi=noCommand;offCommandsi=noCommand;undoCommand=noCommand;,31,public void setCommand(int slot,Command onCommand,Command offCommand)onCo

20、mmandsslot=onCommand;offCommandsslot=offCommand;public void onButtonWasPushed(int slot)onCommandsslot.execute();undoCommand=onCommandsslot;public void offButtonWasPushed(int slot)offCommandsslot.execute();undoCommand=offCommandsslot;public void undoButtonWasPushed()undoCommand.undo();public String t

21、oString()/toString代码,undoCommand变量记录按钮命令。,调用undoCommand实例变量的undo()方法。,32,测试undo按钮public class RemoteLoader public static void main(String args)RemoteControlWithUndo remoteControl=new RemoteControlWithUndo();Light livingRoomLight=new Light(Living Room);LightOnCommand livingRoomLightOn=new LightOnComm

22、and(livingRoomLight);LightOffCommand livingRoomLightOff=new lightOffCommand(livingRoomLight);remoteControl.setCommand(0,livingRoomLightOn,livingRoomLightOff);remoteControl.onButtonWasPushed(0);remoteControl.offButtonWasPushed(0);System.out.println(remoteControl);remoteControl.undoButtonWasPushed();r

23、emoteControl.offButtonWasPushed(0);remoteControl.onButtonWasPushed(0);System.out.println(remoteControl);remoteControl.undoButtonWasPushed();,打开、关闭电灯,然后撤消。,关闭、打开电灯,然后撤消。,33,测试结果,打开电灯,关闭电灯。,电灯命令。,按下撤消按钮。,undo记录的命令。,34,使用状态实现undo要实现撤消的功能,通常需要记录一些状态。下面以天花板上的掉扇为例说明。public class CeilingFan public static f

24、inal int HIGH=3;public static final int MEDIUM=2;public static final int LOW=1;public static final int OFF=0;String location;/例如客厅int speed;public CeilingFan(String location)this.location=location;speed=OFF;public void high()/设置高转速 public void medium()/设置中转速 public void low()/设置中转速 public void off()

25、/关闭掉扇 public int getSpeed()return speed;,35,加入undo到掉扇命令类 public class CeilingFanHighCommand implements Command CeilingFan ceilingFan;int prevSpeed;public CeilingFanHighCommand(CeilingFan ceilingFan)this.ceilingFan=ceilingFan;public void execute()prevSpeed=ceilingFan.getSpeed();ceilingFan.high();publ

26、ic void undo()if(prevSpeed=CeilingFan.HIGH)ceilingFan.high();else if(prevSpeed=CeilingFan.MEDIUM)ceilingFan.medium();else if(prevSpeed=CeilingFan.LOW)ceilingFan.low();else if(prevSpeed=CeilingFan.OFF)ceilingFan.off();,记录掉扇之前的速度变量。,记录掉扇之前的速度。,掉扇速度设置回之前的值。,36,测试天花板掉扇public class RemoteLoader public st

27、atic void main(String args)RemoteControlWithUndo remoteControl=new RemoteControlWithUndo();CeilingFan ceilingFan=new CeilingFan(Living Room);CeilingFanMediumCommand ceilingFanMedium=new CeilingFanMediumCommand(ceilingFan);CeilingFanHighCommand ceilingFanHigh=new CeilingFanHighCommand(ceilingFan);Cei

28、lingFanOffCommand ceilingFanOff=new CeilingFanOffCommand(ceilingFan);remoteControl.setCommand(0,ceilingFanMedium,ceilingFanOff);remoteControl.setCommand(1,ceilingFanHigh,ceilingFanOff);remoteControl.onButtonWasPushed(0);remoteControl.offButtonWasPushed(0);System.out.println(remoteControl);remoteCont

29、rol.undoButtonWasPushed();remoteControl.onButtonWasPushed(1);System.out.println(remoteControl);remoteControl.undoButtonWasPushed();,实例化高速、中速和关闭三个命令。,中速设置到0号插槽,高速设置到1号插槽并加载两个插槽的关闭命令。,中速,高速,37,测试结果,中速打开天花板掉扇,然后关闭。,遥控器命令。,撤消最后一个命令,回到中速。打开高速。,再一次撤消,回到中速。,38,使用宏命令 首先创建宏命令集合。Light light=new Light(Living R

30、oom);TV tv=new TV(Living Room);Stereo stereo=new Stereo(Living Room);Hottub hottub=new Hottub();LightOnCommand lightOn=new LightOnCommand(light);StereoOnCommand stereoOn=new StereoOnCommand(stereo);TVOnCommand tvOn=new TVOnCommand(tv);HottubOnCommand hottubOn=new ottubOnCommand(hottub);,创建所有的装置:电灯、电

31、视、音响和热水器。,39,使用宏命令(续)创建两个数组,记录打开和关闭命令。Command partyOn=lightOn,stereoOn,tvOn,hottubOn;Command partyOff=lightOff,stereoOff,tvOff,hottubOff;MacroCommand partyOnMacro=new MacroCommand(partyOn);MacroCommand partyOffMacro=new MacroCommand(partyOff);public class MacroCommand implements Command Command comm

32、ands;public MacroCommand(Command commands)mands=commands;public void execute()for(int i=0;i commands.length;i+)commandsi.execute();,数组存储一堆命令。,一次性执行数组里的每一个命令。,40,使用宏命令(续)宏命令指定到一个按钮。remoteControl.setCommand(0,partyOnMacro,partyOffMacro);测试是否正常工作。System.out.println(remoteControl);(-Pushing Macro On-);remoteControl.onButtonWasPushed(0);(-Pushing Macro Off-);remoteControl.offButtonWasPushed(0);,41,测试结果,开启宏。,关闭宏。,42,命令模式更多用途:队列请求,工作队列类和进行计算的对象之间是完全解耦的。工作队列不在乎命令做什么,只知道取出命令对象,调用其execute()方法。,多线程处理。,43,命令模式更多用途:日志请求某些应用需要将所有动作记录在日志中,并能在系统死机后重新调用这些动作恢复到之前的状态。,命令接口中新增store()和load()两个方法。,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号