命令模式
命令模式:在软件设计中,我们经常需要像某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求得操作是哪个,我们只需要在程序运行时指定具体得请求接收者即可。
命令模式UML类图
解析:
- Invoker 是调用者
- Command:是命令角色,需要执行的所有命令都在这,可以是接口或者抽象类
- Receiver:接受者角色,知道如何实施和执行一个请求相关的操作
- ConcreteCommand:将一个接收者对象与一个动作绑定,调用接收者相应的操作,实现execute
命令模式的简单实现
Receiver接收者角色
public class LightReceiver {
public void on(){
System.out.println("开灯");
}
public void off(){
System.out.println("关灯");
}
}
Command命令角色
public interface Command {
void execute();
void undo();
}
ConcreteCommand
public class LightOnCommand implements Command {
private LightReceiver lightReceiver;
public LightOnCommand(LightReceiver lightReceiver){
this.lightReceiver = lightReceiver;
}
@Override
public void execute() {
lightReceiver.on();
}
@Override
public void undo() {
lightReceiver.off();
}
}
public class LightOffCommand implements Command {
private LightReceiver lightReceiver;
public LightOffCommand(LightReceiver lightReceiver){
this.lightReceiver = lightReceiver;
}
@Override
public void execute() {
lightReceiver.off();
}
@Override
public void undo() {
lightReceiver.on();
}
}
空命令代码,省去了判断空的操作
public class NoCommand implements Command {
@Override
public void execute() {
}
@Override
public void undo() {
}
}
Invoker调用者
public class RemoteController {
private Command[] onCommands;
private Command[] offCommands;
private Command undoCommand;
public RemoteController(){
this.onCommands = new Command[5];
this.offCommands = new Command[5];
for (int i=0;i<5;i++){
onCommands[i] = new NoCommand();
offCommands[i] = new NoCommand();
}
}
public void setCommand(int no,Command onCommand,Command offCommand){
onCommands[no] = onCommand;
offCommands[no] = offCommand;
}
public void onButtonWasPushed(int no){
onCommands[no].execute();
undoCommand = onCommands[no];
}
public void offButtonWasPushed(int no){
offCommands[no].execute();
undoCommand = offCommands[no];
}
public void undoButtonWasPushed(int no){
undoCommand.undo();
}
}
测试:
public class Client {
public static void main(String[] args) {
LightReceiver lightReceiver = new LightReceiver();
LightOnCommand lightOnCommand = new LightOnCommand(lightReceiver);
LightOffCommand lightOffCommand = new LightOffCommand(lightReceiver);
RemoteController remoteController = new RemoteController();
remoteController.setCommand(0,lightOnCommand,lightOffCommand);
remoteController.onButtonWasPushed(0);
remoteController.undoButtonWasPushed(0);
//开灯
//关灯
}
}
总结
将发起请求对象与执行请求对象解耦。“请求发起者”和“请求执行者”之间的解耦是通过命令对象实现的 不良处导致系统有过多的具体命令类,增加了系统的复杂度。