命令模式(别名:事物、动作)
内容:
将一个请求封装为一个对象,从而使用户可以用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。
结构:
1、接收者:负责执行与请求相关的操作的实例类。
2、命令接口:定义了用于封装请求的若干方法。
3、具体命令:实现了命令接口的具体子类。
4、请求者:其包含了命令接口变量的实例类,通过调用具体命令来执行所封装了请求发方法。
UML类图:
优点:
命令模式满足开闭原则,消除了请求者与接收者之间的耦合,可以将具体命令持久化到媒介中,以此来记录日志,可以对请求者进行排队,每一个请求对应一个具体命令,因而可以按顺序执行这些命令。
适用情境:
程序需要在不同时刻指定、排列、执行命令,程序需要支持撤销操作或宏命令。
这里的宏命令是指一个具体的命令,但其包含了其他具体命令的引用,它可以引起其他具体命令也执行相应方法,即相当于执行了许多具体命令。
使用实例:
//接收者
import java.util.ArrayList;
public class Receiver {
private static ArrayList<Object> objList = new ArrayList<>();
public void add(Object object){
objList.add(object);
}
public void remove(){
if(!objList.isEmpty()){
objList.remove(objList.size()-1);
}
}
public void show(){
for(Object object: objList)
System.out.println(object.toString());
}
}
//命令接口
public interface Command {
public abstract void execute(Object object);
public abstract void undo();
}
//具体命令
public class ConcreteCommand implements Command {
private Receiver receiver;
public ConcreteCommand(Receiver receiver){
this.receiver = receiver;
}
@Override
public void execute(Object object) {
// TODO Auto-generated method stub
this.receiver.add(object);
}
@Override
public void undo() {
// TODO Auto-generated method stub
this.receiver.remove();
}
}
//请求者
public class Invoker {
private Command command;
public void setCommand(Command command){
this.command = command;
}
public void stratExecuteCommand(Object object){
this.command.execute(object);
}
public void undoCommand(){
this.command.undo();
}
}
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
Receiver receiver = new Receiver();
Command command = new ConcreteCommand(receiver);
Invoker invoker = new Invoker();
invoker.setCommand(command);
invoker.stratExecuteCommand("a");
invoker.stratExecuteCommand("b");
invoker.stratExecuteCommand("c");
System.out.println("执行命令后:");
receiver.show();
invoker.undoCommand();
invoker.undoCommand();
System.out.println("撤销命令后:");
receiver.show();
}
}
命令模式的关键就是使用命令对象来封装方法调用,当一个对象请求另一个对象调用其方法来完成任务时,请求者只需和命令对象打交道即可。