您的位置:首页 > 其它

命令模式--command

2013-07-26 15:56 113 查看
定义:将“请求”封装成对象, 以便使用不同的请求、队列、日志来参数化其他对象。 命令模式也支持可撤销的操作。

形象比喻:我有一个MM家里管得特别严,没法见面,只好借助于她弟弟在我们俩之间传送信息,她对我有什么指示,就写一张纸条让她弟弟带给我。这不,她弟弟又传送过来一个COMMAND,为了感谢他,我请他吃了碗杂酱面,哪知道他说:“我同时给我姐姐三个男朋友送COMMAND,就数你最小气,才请我吃面。”

命令模式允许请求的一方和发送的一方独立开来,使得请求的一方不必知道接收请求的一方的接口,更不必知道请求是怎么被接收,以及操作是否执行,何时被执行以及是怎么被执行的。系统支持命令的撤消。

在本文中, 我们采用遥控器来阐述命令模式。 我们用遥控器控制家里的电器。命令(如打开电灯, 打开车库门等)对象将动作和接收者(电灯、车库门)包进对象中,
这个对象只暴露一个excute()方法, 当此方法被调用的时候,接收者就会进行这些动作(如电灯打开, 车库门打开)。从外面来看, 其他对象不知道究竟哪个接受者进行了哪个些动作, 只知道如果调用excute()方法, 请求的目的就会达到。

下面是具体程序:

1、命令接收这: 我们这里举例灯、车库门、音箱;

Light.java

public class Light {
private String name;

public Light(String name) {
this.name = name;
}

public void on() {
System.out.println(name + " Light is on");
}

public void off() {
System.out.println(name + " Light is off");
}
}GarageDoor.java
public class GarageDoor {
private String name;

public GarageDoor(String name) {
this.name = name;
}

public void open() {
System.out.println(name + " Garage Door is open");
}

public void close() {
System.out.println(name + " Garage Door is close");
}
}Stereo.java
public class Stereo {
private String name;

public Stereo(String name) {
this.name = name;
}

public void on() {
System.out.println(name + " Stereo is on");
}

public void off() {
System.out.println(name + " Stereo is off");
}

public void setCd() {
System.out.println(name + " Stereo set CD");
}

public void setDvd() {
System.out.println(name + " Stereo set DVD");
}

public void setRadio() {
System.out.println(name + " Stereo set Radio");
}

public void setVolume(int i) {
System.out.println(name + " Stereo set Volume : " + i);
}
}

2、命令动作:
我们只给出LightOffCommand、LightOffCommand、StereoOnWithCDCommand、StereoOffCommand的代码; GarageDoorOpenCommand与GarageDoorCloseCommand可以参照下面自行补全;

LightOnCommand.java

public class LightOnCommand implements Command {
Light light;

public LightOnCommand(Light light) {
this.light = light;
}

@Override
public void excute() {
light.on();
}
}LightOffCommand.java
public class StereoOffCommand implements Command {
Stereo stereo;

public StereoOffCommand(Stereo stereo) {
this.stereo = stereo;
}

@Override
public void excute() {
stereo.off();
}
}StereoOnWithCDCommand.java
public class StereoOnWithCDCommand implements Command {
Stereo stereo;

public StereoOnWithCDCommand(Stereo stereo) {
this.stereo = stereo;
}

@Override
public void excute() {
stereo.on();
stereo.setCd();
stereo.setVolume(11);
}
}StereoOffCommand.java
public class StereoOffCommand implements Command {
Stereo stereo;

public StereoOffCommand(St
4000
ereo stereo) {
this.stereo = stereo;
}

@Override
public void excute() {
stereo.off();
}
}

3、CommandControl, 遥控器控制
Command.java

public interface Command {
public void excute();
}NoCommand.java  我们将每个按钮指定成NoCommand对象,
以便确保每个按钮都有命令对象。 
public class NoCommand implements Command {
@Override
public void excute() {
}
}RemoteControl.java
public class RemoteControl {
Command[] onCommands;
Command[] offCommands;

public RemoteControl() {
onCommands = new Command[7];
offCommands = new Command[7];

Command noCommand = new NoCommand();
for (int i = 0; i < 7; i++) {
onCommands[i] = noCommand;
offCommands[i] = noCommand;
}
}

public void setCommand(int slot, Command onCommand, Command offCommand) {
onCommands[slot] = onCommand;
offCommands[slot] = offCommand;
}

public void onButtonWasPushed(int slot) {
onCommands[slot].excute();
}

public void offButtonWasPushed(int slot) {
offCommands[slot].excute();
}

public String toString() {
StringBuffer stringBuff = new StringBuffer();
stringBuff.append("\n------Remote Control------------\n");
for (int i = 0; i < onCommands.length; i++) {
stringBuff.append("[slot " + i + "]" + onCommands[i].getClass().getName()
+ " " + offCommands[i].getClass().getName() + "\n");
}
return stringBuff.toString();
}
}

4、测试程序
RemoteControlMain.java

public class RemoteControlMain {
static RemoteControl remote = new RemoteControl();

public static void main(String[] args) {
remoteInit();
System.out.println(remote);

remote.onButtonWasPushed(0);
remote.offButtonWasPushed(0);
remote.onButtonWasPushed(1);
remote.onButtonWasPushed(2);
remote.offButtonWasPushed(1);
remote.offButtonWasPushed(2);
remote.onButtonWasPushed(3);
remote.offButtonWasPushed(3);
}

public static void remoteInit() {
Light light1 = new Light("Living Room");
Light light2 = new Light("Kitchen");
GarageDoor door = new GarageDoor("Living Room");
Stereo stereo = new Stereo("Living Room");

//
LightOnCommand lightOn1 = new LightOnCommand(light1);
LightOffCommand lightOff1 = new LightOffCommand(light1);

LightOnCommand lightOn2 = new LightOnCommand(light2);
LightOffCommand lightOff2 = new LightOffCommand(light2);

GarageDoorOpenCommand garageOpen = new GarageDoorOpenCommand(door);
GarageDoorCloseCommand garageClose = new GarageDoorCloseCommand(door);

StereoOnWithCDCommand stereoOn = new StereoOnWithCDCommand(stereo);
StereoOffCommand stereoOff = new StereoOffCommand(stereo);

remote.setCommand(0, lightOn1, lightOff1);
remote.setCommand(1, lightOn2, lightOff2);
remote.setCommand(2, garageOpen, garageClose);
remote.setCommand(3, stereoOn, stereoOff);
}
}

参考:《Head First模式设计》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: