文章目录
介绍
描述
命令模式设计模式属于行为型模式,将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。
特点
优点:消除了请求发送者和具体指定接收者的耦合,让对象之间的调用关系更加灵活、新的关系也更容易添加。
缺点:可能导致系统产生许多个接收者类。
实现原理
当我们调用时,执行的时序首先是调用者类,然后是命令类,最后是接收者类。也就是说一条命令的执行被分成了三步,即调用者->命令->具体执行者。
适用
-
有常见的撤销(Undo)操作和恢复(Redo)操作。
命令模式
实现
遥控器操作,假设第一行对应电灯打开,则电灯对应为接收者。
第一步:初始化命令接口Command,并创建空实现。
// 创建命令接口
public interface Command {
// 执行动作
void execute();
// 撤销动作
void undo();
}
/**
* 空执行,可用于初始化或者返回为空的条件
* (空对象设计模式)
* 可以省略对空的判断。例如数据库查到为null的结果,可以通过空对象模式返回提示信息
*/
public class NoCommand implements Command{
@Override
public void execute() {
}
@Override
public void undo() {
}
}
第二步:新建电灯接收者类Light,并且新建类LightOn、LightOff去实现Command,完成具体操作。
// 接收者
public class LightReceiver {
public void on(){
System.out.println("电灯 打开 ....");
}
public void off(){
System.out.println("电灯 关闭 ....");
}
}
// 电灯打开
public class LightOn implements Command{
LightReceiver receiver;
public LightOn(LightReceiver receiver) {
this.receiver = receiver;
}
@Override
public void execute() {
// 打开
receiver.on();
}
@Override
public void undo() {
// 对应撤销 积为关闭
receiver.off();
}
}
// 电灯关闭
public class LightOff implements Command{
LightReceiver receiver;
public LightOff(LightReceiver receiver) {
this.receiver = receiver;
}
@Override
public void execute() {
// 关闭
receiver.off();
}
@Override
public void undo() {
// 对应撤销 即为打开
receiver.on();
}
}
第三步:创建真正执行命令的类RemoteController(遥控器),5个槽位,则对应10个开、闭按钮,每行对应一个接收者。
public class RemoteController {
Command[] onCommands; // 所有打开的命令
Command[] offCommands; // 所有关闭的命令
Command undoCommand; // 执行撤销命令
public RemoteController() {
onCommands = new Command[5];
offCommands = new Command[5];
// 初始化 个数 对应按钮个数
for (int i =0;i<5;i++){
// 对每一个命令 实现空操作
onCommands[i] = new NoCommand();
offCommands[i] = new NoCommand();
}
// 撤销按钮初始化
undoCommand = new NoCommand();
}
// 设置相应命令
public void setCommand(int idx,Command on,Command off){
onCommands[idx] = on;
offCommands[idx] = off;
}
// 按下某个打开按钮
public void onBtn(int idx){
onCommands[idx].execute();
// 记录撤销
undoCommand = onCommands[idx];
}
// 按下某个关闭按钮
public void offBtn(int idx){
offCommands[idx].execute();
// 记录撤销
undoCommand = offCommands[idx];
}
// 按下撤销
public void undoBtn(){
// 执行 该 对象的 撤销命令
undoCommand.undo();
undoCommand = new NoCommand();
}
}
第四步:测试。
public class Test {
public static void main(String[] args) {
// 遥控器 初始化操作 ----------
// 创建电灯接收者
LightReceiver receiver = new LightReceiver();
// 创建电灯打开命令
LightOn lightOn = new LightOn(receiver);
LightOff lightOff = new LightOff(receiver);
RemoteController controller = new RemoteController();
// 0 号位置 代表电灯
controller.setCommand(0,lightOn,lightOff);
// Tips : 内部初始化5个位置 当有其他接收者加入 设置对应位置即可
// 遥控器 初始化结束 -----------
// 调用
controller.onBtn(0); // 打开 0号位置 -> 对应电灯的打开
controller.offBtn(0); // 关闭 0 号位置 -> 对应电灯的关闭
controller.undoBtn(); // 执行保留的撤销命令
/*
电灯 打开 ....
电灯 关闭 ....
电灯 打开 ....
*/
}
}