命令模式,腾讯后台开发
}
/** 撤销/恢复命令 */
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 交流。
宏命令
宏命令其实就是一组命令的集合,它是将一组相关命令的集合放在一起执行,并且也可以执行一组命令的撤销操作。
示例代码:
public interface MacroCommand extends Command {
/**
添加一组命令
*/
public void add(List<Command> cmdList);
/**
移除一个命令成员
*/
public void remove(Command cmd);
}
public class ConcreteMacroCommand implements MacroCommand {
/** 持有一组命令的集合 */
private List<Command> commandList = new ArrayList<Command>();
@Override
public void add(List<Command> 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<Command> cmdList = new ArrayList<>();
cmdList.add(command);
cmdList.add(command2);
macroCommand.add(cmdList);
macroCommand.execute();
}
}
命令模式的用途
命令模式的使用场景还是很多的,只要你认为是命令的地方都可以使用命令模式,比如按钮的点击,执行播放操作,实现开关状态,发起一次网络请求等等。命令模式还被广泛的应用在工作队列和日志请求等。
命令模式实现队列请求
想象有一个工作队列:你在某一端添加命令,然后另一端则是线程。线程进行下面的动作:从队列中取出一个命令, 调用它的 execute()方法,等待这个调用完成,然后将此命令对象丢弃.再取出下一个命令 … …
请注意,工作队列类和进行计算的对象之间完全是解耦的。此刻线程可能在进行财务运算,下一刻却在读取网络数据。工作队列对象不在乎到底需要做什么,它们只知道取出命令对象,然后调用其 execute()方法。类似地,它们只要是实现命令模式的对象,就可以放入队列里,当线程可用时,就调用此对象的 execute ( ) 方法。
命令模式实现日志请求
某些应用需要找们将所有的动作都记录在日志中,并能在系统死机之后,重新调用这些动作恢复到之前的状态。通过新增两个方法( store()、 load()),命令模式就能够支持这一点。在 Java 中 , 我们可以利用对象的
序列化( Serialization )实现这些命令对象的持久化。
要怎么做呢?当我们执行命令的时候,将历史记录存储在磁盘中。一旦系统死机,我们就可以将命令对象重新加载, 并成批地依次调用这些对象的 execute ()方法。
评论