命令模式,在软件设计中,我们经常需要发送命令给一些对象,但是不知道请求的接收者是谁,也不知道被请求的操作是哪一个,我们只需要在程序中指定具体的请求接收者即可,可以使用命令模式来设计,命令模式就是将请求封装成对象,将动作请求者和动作执行者解耦。
类图:
命令模式的对象和职责:
1)Invoker:命令的调用者
2)Command:命令角色,所有需要执行的命令都在这里
3)Receiver:接收者角色,知道如何实施和执行一个命令的操作
4)ConcreteCommand:实现了抽象命令类的方法,也是具体接受者的关联的类。同过具体的execute方法调用处理类的方法处理请求。
案例
遥控器遥控家电案例:有一个遥控器上面有许多按钮,需要设计程序使得一个按钮可以执行一个命令操作家用电器。
Command接口
public interface Command {
public void excute();
}
具体的命令
public class LightOnCommand implements Command {
private LightReceiver light;
public LightOnCommand(LightReceiver light) {
this.light = light;
}
@Override
public void excute() {
light.on();
}
}
public class LightOffCommand implements Command {
private LightReceiver light;
public LightOffCommand(LightReceiver light) {
this.light = light;
}
@Override
public void excute() {
light.off();
}
}
一个空命令,便于初始化
public class NoCommand implements Command {
@Override
public void excute() {
}
}
命令的接收者
public class LightReceiver {
public void on(){
System.out.println("电灯打开了");
}
public void off(){
System.out.println("电灯关闭了");
}
}
命令的调用者
public class Invoker {
Command[] Commands;
public Invoker(){
Commands=new Command[2];
for(int i=0;i<2;i++){
Commands[i]=new NoCommand();
}
}
//给按钮设置需要的指令
public void setCommand(int no,Command Command){
Commands[no]=Command;
}
public void PushButton(int no){
Commands[no].excute();
}
}
客户端调用
public class Client {
public static void main(String[] args) {
LightReceiver light=new LightReceiver();
Command lightoffcommand=new LightOffCommand(light);
Command lightoncommand=new LightOnCommand(light);
Invoker invoker=new Invoker();
invoker.setCommand(0,lightoncommand);
invoker.setCommand(1,lightoffcommand);
invoker.PushButton(0);
invoker.PushButton(1);
}
}
可见命令模式可以将命令的命令的调用者和命令的接收者解耦,命令的调用者不需要知道需要具体的接收者是谁,是如何实现的,命令对象会负责让接收者执行请求的动作,命令对象是调用者与接收者之间的纽带。
缺点是某些情况造成命令类过多,增加了系统的复杂度。