命令模式定义:命令模式将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其它对象。命令模式也支持可撤销操作。
这个模式貌似和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!