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