Behavioral Patterns Part 2/11: Command Pattern
目录
Definition
Command Pattern 把一个请求封装成对象,从而使客户端可以更灵活的处理请求,包括 请求队列,对请求做日志处理,以及撤销(undo) 操作。
一句话:
An object encapsulates everything needed to execute a method in another object.
何时使用?当希望把request封装成对象,或者希望request可以存储在消息队列中,或者希望可以对request做undo(撤销)操作时。
使用频率: Medium High
UML Class Diagram
各 类 说明如下:
- Command - 声明了一个接口,用来执行一个操作(Operation);
- ConcreteCommand - 实现 Command 接口,通过执行 Receiver 的方法实现了 Command 的 Execute 方法;
- Client - 创建一个 ConcreteCommand 对象,设置它的 receiver;
- Invoker - 让 command 执行 request;
- Receiver - 负责执行具体的操作;
流程:
Client 请求执行一个 Command –>
Invoker 获取这个 Command,封装起来,放入一个队列 –>
ConcreteCommand 把 Client 请求的 command 交由 Receiver 执行。
Implementation
这里以一个饭店点餐的例子来说明 Command Pattern 。
客人(Client) 点菜(创建Concrete Command) –>
店小二(Invoker)记录下来各种 点菜记录(先来后到的记录在一个纸条上) –>
店小二(Invoker) 通知 厨师(Receiver) 根据菜单(Concrete Command List) 来 做菜(Action)。
// Order.java
package designpatterns.behavioralpatterns.command;
/** Command **/
public abstract class Order {
protected Cook cook;
public Order(Cook cook) {
this.cook = cook;
}
public abstract void execute();
}
// OrderImpl.java
package designpatterns.behavioralpatterns.command;
/** Concrete Command **/
class ChuanDishOrder extends Order {
public ChuanDishOrder(Cook cook) {
super(cook);
}
@Override
public void execute() {
cook.makeChuanDish();
}
}
/** Concrete Command **/
class XiangDishOrder extends Order {
public XiangDishOrder(Cook cook) {
super(cook);
}
@Override
public void execute() {
cook.makeXiangDish();
}
}
/** Concrete Command **/
class HuiDishOrder extends Order {
public HuiDishOrder(Cook cook) {
super(cook);
}
@Override
public void execute() {
cook.makeHuiDish();
}
}
// Waiter.java
package designpatterns.behavioralpatterns.command;
import java.util.LinkedList;
import java.util.Queue;
/** Invoker **/
class Waiter {
private Queue<Order> ordersQueue = new LinkedList<>();
public Waiter() {}
public void placeOrder(Order order) {
ordersQueue.offer(order);
ordersQueue.poll().execute();
}
}
// Cook.java
package designpatterns.behavioralpatterns.command;
/** Receiver **/
public class Cook {
public void makeChuanDish() {
System.out.println("Make Some Chuan Dish.");
}
public void makeXiangDish() {
System.out.println("Make Some Xiang Dish.");
}
public void makeHuiDish() {
System.out.println("Make Some Hui Dish.");
}
}
// CommandDemo.java
package designpatterns.behavioralpatterns.command;
public class CommandDemo {
public static void main(String[] args) {
Cook cook = new Cook(); // 厨子
HuiDishOrder hdo = new HuiDishOrder(cook); // 徽菜菜单
XiangDishOrder xdo = new XiangDishOrder(cook); // 湘菜菜单
ChuanDishOrder cdo = new ChuanDishOrder(cook); // 川菜菜单
Waiter waiter = new Waiter();
waiter.placeOrder(hdo); // 客人点徽菜
waiter.placeOrder(hdo); // 客人点徽菜
waiter.placeOrder(xdo); // 客人湘菜菜
waiter.placeOrder(cdo); // 客人点川菜
}
}
// output
Make Some Hui Dish.
Make Some Hui Dish.
Make Some Xiang Dish.
Make Some Chuan Dish.