命令模式--command

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

形象比喻:我有一个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(Stereo 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模式设计》







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值