命令模式是一种行为模式,通过将动作封装成对象,实现命令请求者和命令接收者之间的解耦。调用者只需要简单的下达命令,然后等待命令完成即可,对执行者如何处理命令完全不关心。
命令模式中的角色:
Command
(命令接口):为所有命令声明一个公共接口,定义一个execute()
方法。ConcreteCommand
(具体命令):实现命令接口的某一个具体命令,定义了该命令的动作和具体的执行者。Invoker
(命令请求者):持有一个具体的命令对象,在某个时间点调用命令对象的execute()
方法。Receiver
(命令接收者):接收命令并执行。Client
(客户端):
UML
类图:
以遥控器打开/关闭电视为例。
ICommand
接口:
public interface ICommand {
void execute();
}
Receiver
也就是命令的真正执行者,这里是电视和灯。
Tv
:
public class Tv {
public void on() {
System.out.println("打开电视.");
}
public void off() {
System.out.println("关闭电视.");
}
}
Light
:
public class Light {
public void turnOn() {
System.out.println("打开灯.");
}
public void turnOff() {
System.out.println("关闭灯.");
}
}
具体的命令有四个:打开电视、关闭电视、打开灯、关闭灯。
TvOnCommand
:
public class TvOnCommand implements ICommand {
private Tv tv;
public TvOnCommand(Tv tv) {
this.tv = tv;
}
@Override
public void execute() {
this.tv.on();
}
}
TvOffCommand
:
public class TvOffCommand implements ICommand {
private Tv tv;
public TvOffCommand(Tv tv) {
this.tv = tv;
}
@Override
public void execute() {
this.tv.off();
}
}
LightOnCommand
:
public class LightOnCommand implements ICommand {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
this.light.turnOn();
}
}
LightOffCommand
:
public class LightOffCommand implements ICommand {
private Light light;
public LightOffCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
this.light.turnOff();
}
}
Invoker
在这里就是遥控器,它持有具体的命令对象,并在某个时间点调用命令。
RemoteControl
:
public class RemoteControl {
public static final int TV_ON = 0;
public static final int TV_OFF = 1;
public static final int LIGHT_ON = 2;
public static final int LIGHT_OFF = 3;
private List<ICommand> commands;
public RemoteControl() {
commands = new ArrayList<>(4);
Tv tv = new Tv();
commands.add(new TvOnCommand(tv));
commands.add(new TvOffCommand(tv));
Light light = new Light();
commands.add(new LightOnCommand(light));
commands.add(new LightOffCommand(light));
}
public void action(int i) {
if (i < 0 || i > 3) {
return;
}
commands.get(i).execute();
}
}
客户端通过“按”遥控器来触发某个命令:
Client
:
public class Client {
public static void main(String[] args) {
RemoteControl remoteControl = new RemoteControl();
remoteControl.action(RemoteControl.TV_ON);
remoteControl.action(RemoteControl.TV_OFF);
remoteControl.action(RemoteControl.LIGHT_ON);
remoteControl.action(RemoteControl.LIGHT_OFF);
}
}
数据结果: