请求某个命令执行者执行命令时,最直接的方式是客户端直接传入命令给执行者,但这样就无法管理命令(或者说只能由客户端来管理),加重了客户端的负担。此类场景可以将命令封装成类,其内持有命令执行者实例,另有一个execute
方法,该方法调用命令执行者实例的执行方法。再引入一个命令请求者(或称命令传递者,命令管理者)类来持有命令集合实例,其内有追加命令方法,删除命令方法,最重要的是有一个传递命令的方法request
,该方法通过调用其持有的命令对象的execute
方法来实现请求(execute
内部调用了命令执行者自身的执行方法)。
package com.yukiyama.pattern.behavior;
import java.util.ArrayList;
import java.util.List;
/**
* 命令模式
*/
public class CommandDemo {
public static void main(String[] args) {
// 声明命令执行者
Chef chef = new Chef();
// 声明具体命令,通过构造器传入该命令对应的执行者(本例只有一个执行者)
Order muttonOrder = new MuttonOrder(chef);
Order wingsOrder = new ChickenWingsOrder(chef);
// 声明命令请求者
Waiter waiter = new Waiter();
// 将命令传入请求者内
waiter.addOrder(muttonOrder);
waiter.addOrder(wingsOrder);
// 命令请求者执行request方法,输出"烤羊肉串",“烤鸡翅”
waiter.request();
}
}
/**
* 抽象命令类
* 持有命令执行者类Chef,通过有参构造器传入Chef来初始化。有一个execute抽象方法。
*/
abstract class Order{
protected Chef chef;
public Order(Chef chef){
this.chef = chef;
}
public abstract void execute();
}
/**
* 具体命令类
* 实现抽象命令类,实现execute方法,方法内部调用其持有的Chef的做菜方法。
* 下例是点羊肉串的命令MuttonOrder,execute方法内调用Chef的做羊肉串方法
* makeMutton。
*/
class MuttonOrder extends Order{
public MuttonOrder(Chef chef) {
super(chef);
}
@Override
public void execute() {
chef.makeMutton();
}
}
/**
* 具体命令类
* 下例是点鸡翅的命令ChickenWingsOrder,execute方法内调用Chef的做鸡翅
* 方法makeChickenWings。
*/
class ChickenWingsOrder extends Order{
public ChickenWingsOrder(Chef chef) {
super(chef);
}
public void execute() {
chef.makeChickenWings();
}
}
/**
* 命令请求者类
* 持有一个命令实例集合List<Order>。维护管理命令的方法addOrder,cancel,
* request。其中传递命令的请求方法request遍历该类持有的命令集合,并执行命令
* 类的execute方法。
*/
class Waiter{
private List<Order> orders = new ArrayList<>();
public void addOrder(Order order) {
orders.add(order);
}
public void cancelOrder(Order order) {
orders.remove(order);
}
public void request() {
for(Order order : orders) {
order.execute();
}
}
}
/**
* 命令执行者类
* 真正执行命令的角色,维护做菜方法。
* 下例是烤羊肉串MakeMutton和烤鸡翅MakeChickenWings方法。
*/
class Chef{
public void makeMutton() {
System.out.println("烤羊肉串");
}
public void makeChickenWings() {
System.out.println("烤鸡翅");
}
}