一、定义
将一个请求封装成一个对象,从而让用户使用不同的请求把客户端参数化;对请求排队或者记录请求日志,以及支持可撤销操作。
二、使用场景
需要对请求排队或者记录请求日志,以及支持可撤销操作时,可使用命令模式。
三、UML类图
命令模式
Receiver:命令接受者,执行具体命令。
Command:抽象命令,定义所有具体命令类的抽象接口。
ConcreteCommand:具体命令,实现抽象命令类中定义的接口。
Invoker:请求者,调用命令对象执行具体的请求。
Client:客户端。
四、实现
//命令处理者
public class Receiver {
public void action() {
System.out.println("执行具体操作");
}
}
//命令接口
public interface Command {
void execute();
}
//具体命令
public class ConcreteCommand implements Command {
private Receiver receiver;
public ConcreteCommand(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void execute() {
receiver.action();
}
}
//命令请求者
public class Invoker {
private Command command;
public Invoker(Command command) {
this.command = command;
}
public void action() {
command.execute();
}
}
//客户端
public class Client {
public static void main(String[] args) {
Receiver receiver = new Receiver();
Command command = new ConcreteCommand(receiver);
Invoker invoker = new Invoker(command);
invoker.action();
}
}
五、应用
例子:烤肉串
//烤肉串者
public class Barbecuer {
public void bakeMutton() {
System.out.println("烤羊肉串");
}
public void bakeChickenWing() {
System.out.println("烤鸡翅");
}
}
//抽象命令
public abstract class Command {
protected Barbecuer receiver;
public Command(Barbecuer receiver) {
this.receiver = receiver;
}
public abstract void executeCommand();
}
//烤羊肉串命令
public BakeMuttonCommand extends Command {
public BakeMuttonCommand(Barbecuer receiver) {
super(receiver);
}
@Override
public void executeCommand() {
receiver.bakeMutton();
}
}
//烤鸡翅命令
public BakeChickenWingCommand extends Command {
public BakeChickenWingCommand(Barbecuer receiver) {
super(receiver);
}
@Override
public void executeCommand() {
receiver.bakeChickenWing();
}
}
//服务员
public class Waiter {
private List<Command> orders = new ArrayList<>();
public void setOrder() {
if(command.toString().equals("BakeChickenWingCommand")) {
System.out.println("服务员:鸡翅没有了,请点别的烧烤。");
} else {
orders.add(command);
System.out.println("增加订单:" + command.toString());
}
}
public void cancelOrder(Command command) {
orders.remove(command);
System.out.println("取消订单:" + command.toString());
}
public void notify() {
foreach(Command cmd : orders) {
cmd.executeCommand();
}
}
}
//客户端
public class Client {
public static void main(String[] args) {
Barbecuer boy = new Barbecuer();
Command bakeMuttonCommand1 = new BakeMuttonCommand(boy);
Command bakeMuttonCommand2 = new BakeMuttonCommand(boy);
Command bakeChickenWingCommand1 = new BakeChickenWingCommand(boy);
Waiter girl = new Waiter();
girl.setOrder(bakeMuttonCommand1);
girl.setOrder(bakeMuttonCommand2);
girl.setOrder(bakeChickenWingCommand1);
girl.notify();
}
}
六、总结
命令模式的应用其实可以用一句话来概述,就是将行为请求者与行为实现者解耦。通过引入一个中间者可以实现对请求排队或者记录请求日志,以及支持可撤销操作。