Behavioral Patterns Part 2/11: Command Pattern

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(撤销)操作时。

使用频率:Frequncet of use Medium High


UML Class Diagram

Command Pattern

各 类 说明如下:

  • 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.
posted @ 2016-06-27 17:09  1202zhyl  阅读(151)  评论(0编辑  收藏  举报