命令模式,阿里P8面试官都说太详细了

/*具体的接收者/

public class ConcreteReceiver extends Receiver {

@Override

public void action() {

System.out.println(“执行真正的操作”);

}

}

/** 调用者 */

public class Invoker {

/** 持有命令对象 */

private Command command = null;

/** 设置命令 */

public void setCommand(Command command){

this.command = command;

}

/** 执行命令 */

public void action(){

command.execute();

}

/** 撤销/恢复命令 */

public void undo(){

command.undo();

}

}

public class Client {

public static void main(String[] args) {

//创建调用者对象

Invoker invoker = new Invoker();

//创建一个具体的接收者对象

Receiver receiver = new ConcreteReceiver();

//创建一个具体的命令

Command command = new ConcreteCommand(receiver);

//给调用者设置命令

invoker.setCommand(command);

//调用者执行命令

invoker.action();

//创建第二个接收者

Receiver receiver2 = new ConcreteReceiver();

//创建第二个命令使用新的接收者

Command command2 = new ConcreteCommand(receiver2);

invoker.setCommand(command2);

invoker.action();

//创建一个撤销命令

Command undoCommand = new ConcreteCommand(receiver);

invoker.setCommand(undoCommand);

//调用者撤销操作

invoker.undo();

}

}

命令模式中,调用者持有命令对象,而命令对象持有真正的操作接收者对象,客户端代码中最终通过调用者对象去执行相关命令,使得接收者对象跟客端户解耦。调用者可以在需要的时候动态的设置不同命令去执行,更加灵活。

当然,在上面的代码中,如果你的Receiver对象在整个系统中是不变的只有一个实现类,可以考虑将它封装到ConcreteCommand类的内部,就是说Receiver receiver = new ConcreteReceiver()这句可以放到ConcreteCommand的构造函数中,这样客户端可以做到完全不用关心Receiver的细节,只跟Command交流。

《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》

【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享

宏命令

宏命令其实就是一组命令的集合,它是将一组相关命令的集合放在一起执行,并且也可以执行一组命令的撤销操作。

示例代码:

public interface MacroCommand extends Command {

/**

  • 添加一组命令

*/

public void add(List cmdList);

/**

  • 移除一个命令成员

*/

public void remove(Command cmd);

}

public class ConcreteMacroCommand implements MacroCommand {

/** 持有一组命令的集合 */

private List commandList = new ArrayList();

@Override

public void add(List cmdList) {

commandList.addAll(cmdList);

}

@Override

public void remove(Command cmd) {

commandList.remove(cmd);

}

/**

  • 执行一组命令

*/

@Override

public void execute() {

for(Command cmd : commandList){

cmd.execute();

}

}

/**

  • 撤销一组命令

*/

@Override

public void undo() {

for(Command cmd : commandList){

cmd.undo();

}

}

}

public class Client {

public static void main(String[] args) {

MacroCommand macroCommand = new ConcreteMacroCommand();

List cmdList = new ArrayList<>();

cmdList.add(command);

cmdList.add(command2);

macroCommand.add(cmdList);

macroCommand.execute();

}

}

命令模式的用途

命令模式的使用场景还是很多的,只要你认为是命令的地方都可以使用命令模式,比如按钮的点击,执行播放操作,实现开关状态,发起一次网络请求等等。命令模式还被广泛的应用在工作队列和日志请求等。

命令模式实现队列请求

想象有一个工作队列:你在某一端添加命令,然后另一端则是线程。线程进行下面的动作:从队列中取出一个命令, 调用它的execute()方法,等待这个调用完成,然后将此命令对象丢弃.再取出下一个命令 … …

请注意,工作队列类和进行计算的对象之间完全是解耦的。此刻线程可能在进行财务运算,下一刻却在读取网络数据。工作队列对象不在乎到底需要做什么,它们只知道取出命令对象,然后调用其execute()方法。类似地,它们只要是实现命令模式的对象,就可以放入队列里,当线程可用时,就调用此对象的 execute ( ) 方法。

命令模式实现日志请求

某些应用需要找们将所有的动作都记录在日志中,并能在系统死机之后,重新调用这些动作恢复到之前的状态。通过新增两个方法( store()、 load()),命令模式就能够支持这一点。在 Java 中 , 我们可以利用对象的序列化( Serialization )实现这些命令对象的持久化。

上一篇:设计模式——命令模式


下一篇:2109春第一次课程设计实验报告