您的位置:首页 > 其它

命令模式(Command Pattern)

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

这个模式貌似和Observer Pattern很像,实际上区别不小:

1,Observer Pattern是我有新数据,我给你新数据或者你来取新数据,是数据的传递;Command Pattern是我下达命令,你执行命令,是方法的调用(从这能看出,2种模式处理的场景并不相同)

2,Observer Pattern中没有ConcreteCommand对Receiver的封装;而在Command Pattern中,ConcreteCommand扮演的角色像是一个调用的中继

3,Command Pattern中的Command是可以回滚的

4,Observer Pattern中的Observer是一个接口或者抽象类,Command Pattern中没有

Command Pattern的基本模型:



Command Pattern举例,通过该图可以清楚的看出Command Pattern的优势:

Invoke和Receiver之间是松耦合的,也即,对Invoke来说,并不知道最终调用的Receiver是哪一个

Receiver被封装在相对应的Command中,只要将适当的Command注入给Invoke,当调用Invoke.act()时,将自动调用Command封装的Receiver

特定的ConcreteCommand和特定的Receiver紧耦合,这是没问题的,特定的ConcreteCommand本来就是用来封装特定的Receiver的,并且Invoke针对的是Command接口,并不和特定的ConcreteCommand类耦合



public class Client {
	public static void main(String[] args) {
		Receiver r = new Receiver();
		Command c = new ConcreteCommand(r);
		Invoke invoke = new Invoke();
		invoke.setCommand(c);
		invoke.act();
	}
}
public class Invoke {
	Command command;
	
	public void setCommand(Command command){
		this.command = command;
	}
	
	public void act(){
		this.command.execute();
	}
}
public interface Command {
	public void execute();
}
public class ConcreteCommand implements Command {
	private Receiver receiver;
	
	public ConcreteCommand(Receiver receiver){
		 this.receiver = receiver;
	}
	
	public void execute() {
		receiver.work();
	}
}
public class Receiver {
	public void work(){
		System.out.println("begin to work");
	}
}

写一个稍微复杂点的例子,宙斯盾防御系统,中央系统会下达命令,控制驱逐舰上的火炮,导弹发射架:



public class CenterSystem {
	public static void main(String[] args){
		WeaponSystem ws = new WeaponSystem();
		Missile m = new Missile();
		Cannon c = new Cannon();
		MissileFireCommand mfc = new MissileFireCommand(m);
		MissileStopCommand msc = new MissileStopCommand(m);
		CannonFireCommand cfc = new CannonFireCommand(c);
		CannonStopCommand csc = new CannonStopCommand(c);
		ws.setCommand(0, mfc);
		ws.setCommand(1, msc);
		ws.setCommand(2, cfc);
		ws.setCommand(3, csc);
		
		ws.work();
		ws.undo();
	}
}
public class WeaponSystem {
	private Command[] commands;
	
	public WeaponSystem(){
		commands = new Command[10];
		for(int i = 0 ; i <= 9 ;i++){
			commands[i] = new NoCommand();
		}
	}
	
	public void setCommand(Integer position,Command command){
		if(position >= 0 && position <= 9){
			commands[position] = command;
		}
	}
	
	public void work(){
		for(Command command : commands){
			command.execute();
		}
	}
	
	public void undo(){//撤销之前的一系列动作
		for(int i = 9 ; i >=0 ; i--){
			commands[i].undo();
		}
	}
}
public interface Command {
	public void execute();
	
	public void undo();
}
public class MissileFireCommand implements Command {
	private Missile missile;

	public MissileFireCommand(Missile missile) {
		this.missile = missile;
	}

	public void execute() {
		missile.fire();
	}

	public void undo() {
		missile.stop();
	}
}
public class MissileStopCommand implements Command {
	private Missile missile;
	
	public MissileStopCommand(Missile missile){
		this.missile = missile;
	}
	
	public void execute() {
		missile.stop();
	}

	public void undo() {
		missile.fire();
	}
}
public class CannonFireCommand implements Command {
	private Cannon cannon;
	
	public CannonFireCommand(Cannon cannon){
		this.cannon = cannon;
	}
	
	public void execute() {
		cannon.fire();
	}

	public void undo() {
		cannon.stop();
	}
}
public class CannonStopCommand implements Command {
	private Cannon cannon;
	
	public CannonStopCommand(Cannon cannon){
		this.cannon = cannon;
	}
	
	public void execute() {
		cannon.stop();
	}

	public void undo() {
		cannon.fire();
	}
}
public class NoCommand implements Command {
	public void execute() {
	}

	public void undo() {
	}
}
public class Missile {
	public void fire(){
		System.out.println("Missile fire!");
	}

	public void stop(){
		System.out.println("Missile stop!");
	}
}
public class Cannon {
	public void fire(){
		System.out.println("Cannon fire!");
	}
	
	public void stop(){
		System.out.println("Cannon stop!");
	}
}
运行结果:

Missile fire!
Missile stop!
Cannon fire!
Cannon stop!
Cannon fire!
Cannon stop!
Missile fire!
Missile stop!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: