命令模式:将一个请求封装成一个对象,从而可以使用不同的请求对客户端进行参数化,还可以记录请求日志和撤销请求。
当我们发出一个或者多个请求的时候,如果请求的接收者和执行者重合的话,会导致职责过重,难以对请求进行管理。如果将请求接收者和请求执行者分开,就可以比较好地对请求进行管理和完成。一个典型的例子就是餐厅点餐,服务员负责接受客人点餐,厨师负责完成炒菜。
基本实现
执行者:
public class Executor {
public void execute() {
System.out.println("Executor executes");
}
}
命令类及其具体实现,与执行者相关联,命令的执行就是调用执行者去执行:
public abstract class Command {
protected Executor executor;
public Command(Executor executor) {
this.executor = executor;
}
public abstract void execute();
}
class ConcreteCommand extends Command {
public ConcreteCommand(Executor executor) {
super(executor);
}
@Override
public void execute() {
executor.execute();
}
}
命令接收者,依赖于命令,接收者的执行方法就是执行命令:
public class Receiver {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void executeCommand() {
command.execute();
}
}
测试类:
public class Main {
public static void main(String[] args) {
final Executor executor = new Executor();
final Command command = new ConcreteCommand(executor);
final Receiver receiver = new Receiver();
receiver.setCommand(command);
receiver.executeCommand();
}
}
输出:
Executor executes
示例实现:
厨师类:
public class Chef {
public void kungPowChicken() {
System.out.println("老师傅炒出宫保鸡丁这道菜");
}
public void seaweedSoup() {
System.out.println("老师傅熬制上等紫菜汤");
}
public void rice() {
System.out.println("老师傅准备特级香米饭");
}
}
点菜命令类及其子类:
public abstract class Order {
protected Chef chef;
public Order(Chef chef) {
this.chef = chef;
}
public abstract void execute();
}
class KungPowChickenOrder extends Order {
public KungPowChickenOrder(Chef chef) {
super(chef);
}
@Override
public void execute() {
chef.kungPowChicken();
}
@Override
public String toString() {
return "宫保鸡丁";
}
}
class SeaweedSoupOrder extends Order {
public SeaweedSoupOrder(Chef chef) {
super(chef);
}
@Override
public void execute() {
chef.seaweedSoup();
}
@Override
public String toString() {
return "海带汤";
}
}
class RiceOrder extends Order {
public RiceOrder(Chef chef) {
super(chef);
}
@Override
public void execute() {
chef.rice();
}
@Override
public String toString() {
return "香米饭";
}
}
服务员类,,可以对接收的命令进行记录,还可以进行判断命令是否有效,以及统一执行命令:
public class Waiter {
private List<Order> orders = new ArrayList<>();
public void addOrder(Order order) {
orders.add(order);
System.out.println("客人点了" + order);
}
public void deleteOrder(Order order) {
orders.remove(order);
System.out.println("客人不点" + order + "了");
}
public void finishOrder() {
for (Order order : orders) {
order.execute();
}
}
}
测试类:
public class Main {
public static void main(String[] args) {
final Chef chef = new Chef();
final KungPowChickenOrder kungPowChickenOrder = new KungPowChickenOrder(chef);
final SeaweedSoupOrder seaweedOrder = new SeaweedSoupOrder(chef);
final RiceOrder riceOrder = new RiceOrder(chef);
final Waiter waiter = new Waiter();
waiter.addOrder(kungPowChickenOrder);
waiter.addOrder(seaweedOrder);
waiter.addOrder(riceOrder);
System.out.println();
waiter.deleteOrder(riceOrder);
System.out.println();
waiter.finishOrder();
}
}
输出:
客人点了宫保鸡丁
客人点了海带汤
客人点了香米饭
客人不点香米饭了
老师傅炒出宫保鸡丁这道菜
老师傅熬制上等紫菜汤