先来一波命令模式的定义:在软件设计中,我们经常会遇到某些对象发送请求,然后某些对象接受请求后执行,但发送请求的对象可能并不知道接受请求的对象是谁,执行的是什么动作。此时可通过 命令模式 来实现,让发送者和接受者完全的松耦合,这样可大大增强程序的灵活性。接着看一下UML类图。
举个例子来详细说明一下,以head First中的命令模式为例。假设现在有遥控器,要控制大厅的灯,大厅的音响,房间的空调。你当然可以让遥控器来直接控制它们,但是如果这样的话,你就得考虑不同的实现了,因为灯,音响都是不一样的,以后也会出现其他的电器,那么为了解耦,就只是让遥控器间接地控制它们。与上面的类图进行对应的话
(1)Invoker:遥控器
(2)Command:遥控器的按钮
(3)Receiver:实际接受的对象(比如灯、音响)
(4)ConcreateCommand:具体的按钮(开灯键、关灯键)
//所有按钮的超类
public interface Command {
//执行键
void execute();
//撤销键
void undo();
}
//开灯
public class LightOnCommand implements Command{
Light light;
public LightOnCommand(Light light){
this.light=light;
}
@Override
public void execute() {
light.on();
}
@Override
public void undo() {
light.off();
}
}
//关灯
public class LightOffCommand implements Command{
Light light;
public LightOffCommand(Light light){
this.light=light;
}
@Override
public void execute() {
light.off();
}
@Override
public void undo() {
light.on();
}
}
//具体被操作的对象
public class Light {
public void on() {
System.out.println("开灯");
}
public void off() {
System.out.println("关灯");
}
}
//遥控器
public class Remote {
Command[] onCommands;
Command[] offCommands;
Command undoCommand;
public Remote() {
onCommands = new Command[3];
offCommands = new Command[3];
}
public void setCommand(int index,Command onCommand,Command offCommand) {
onCommands[index] = onCommand;
offCommands[index] = offCommand;
}
public void onButton(int index) {
onCommands[index].execute();
undoCommand=onCommands[index];
}
public void offButton(int index) {
offCommands[index].execute();
undoCommand=offCommands[index];
}
public void undo() {
undoCommand.undo();
}
}
//测试代码
public static void main(String[] args) {
Remote remote= new Remote();
Light l=new Light();
LightOnCommand lo=new LightOnCommand(l);
LightOffCommand lf=new LightOffCommand(l);
remote.setCommand(0, lo, lf);
remote.onButton(0);//开灯
remote.offButton(0);//关灯
remote.undo();//开灯
}
这里只举出了一个灯的实例,其他的都是类似的。
总结一下,重要的是思想,让命令的接受者和实际的被控制者之间多一层控制者,让接受者不必过多的去思考被控制者的实现,而只去调用控制者的api即可控制,真正的控制是在控制者这一步做到的。这样可以更好地拓展。