命令模式定义:命令模式通过被称为Command的类封装了对目标对象的调用行为以及调用参数。将一个请求封装称为一个命令,从而使你不同的请求对客户进行参数化;队请求排队或记录请求日志,以及支持可撤销的操作。
优点:解耦了调用者与接受者之间的联系。调用者调用一个操作,接受者接受请求执行相应的动作,因为使用命令模式解耦,调用者无需知道接受者任何借口。
缺点:造成出现过多的具体命令类。
可以类比的例子如:遥控器操纵电视机,各个操作电视机的命令(下面Demo中的NoCommand、OffCommand、OnCommand);遥控器,承载各种命令(Invoker);人,操控遥控器来实现对各种命令的调用(Test)。
下面实现了一个Command模式的Demo
Command接口
package test;
public interface Command {
public void execute();
public void undo();
}
NoCommand类:Command接口实现类1
package test;
public class NoCommand implements Command {
@Override
public void execute() {
}
@Override
public void undo() {
}
}
OffCommand类:Command接口实现类2
package test;
public class OffCommand implements Command {
private Light light;
public OffCommand(Light l) {
this.light = l;
}
@Override
public void execute() {
light.off();
}
@Override
public void undo() {
light.on();
}
}
OnCommand类:Command接口实现类3
package test;
public class OnCommand implements Command {
private Light light;
public OnCommand(Light l) {
this.light = l;
}
@Override
public void execute() {
light.on();
}
@Override
public void undo() {
light.off();
}
}
Invoker类:遥控器
package test;
public class Invoker {
private Command command;
private Command undoCommand;
public Invoker() {
command = new NoCommand();
undoCommand = new NoCommand();
}
public void setCommand(Command c) {
this.command = c;
}
public void pressButton() {
this.command.execute();
undoCommand = command;
}
public void undoPress() {
undoCommand.undo();
}
}
Test测试类:人
package test;
public class Test {
public static void main(String[] args) {
Light light = new Light();
Command on = new OnCommand(light);
Command off = new OffCommand(light);
Invoker invoker = new Invoker();
invoker.setCommand(off);
invoker.pressButton();
System.out.println("Light off pressButton:" + light.getStatus());
invoker.undoPress();
System.out.println("Light off undoPress:" + light.getStatus());
}
}
输出结果:
Light off pressButton:OFF
Light off undoPress:ON