###定义 命令模式将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他的对象。命令模式也支持可以撤销的操作。
命令模式将客户端和执行的命令的具体的对象解耦,命令调用者将执行命令的接受者包装起来,对外开放一个调用执行对象的方法,但是命令调用者并不关心具体的执行方式,而是由内部的具体的接受者去执行具体的命令。
命令模式类图
###实例 命令模式在我们的生活中一个显而易见的例子就是我们在饭店点餐的过程,我们在菜单上写下我们需要的菜(创建一个命令对象),然后由服务员统一整理菜单交给厨师去处理。这一个过程中服务员(命令调用者)和具体的执行者(厨师)之间实现了解耦,服务员根本不用关心怎么去炒菜,只需要把菜单交给厨师,通知厨师要烧菜就ok。我们在点菜(将需要的菜写进菜单)的过程就相当于在调用者中注册命令的过程。下面用代码进行解释。
首先定义一个调用者也就是服务员。
public class Waiter {
Command command=null;
//顾客点菜的过程相当于将需要做的菜的命令传入调用者的过程
public void setCommand(Command command ){
this.command=command;
}
//相当于服务员对厨师说这些菜需要炒了,(此处为了简化只传入了一个菜)对于命令模式来说,一个命令下面可以由多个动作
//也就是宏命令。
public void orderUp(){
command.execute();
}
}
复制代码
定义一命令(菜品)的接口,同时定义一个具体的命令(菜品)
public interface Command {
//所有的实现命令的类都需要实现execute 方法。
public void execute();
}
public class FanQieChaoDan implements Command{
//这里的具体的执行者(Receiver)就是厨师
Cook cook=null;
public FanQieChaoDan(Cook cook){
this.cook=cook;
}
public void execute(){
cook.cooking();
}
}
复制代码
定义接受者(厨师)
public class Cook{
public void cooking(){
//剧情需要,一个厨师只会做一道菜
System.out.println("Now you gey FanQieChaoDan!");
}
}
复制代码
下面开始模顾客点菜的过程
public class Order{
public static void main(String[] args) {
//首先需要一个服务员
Waiter waiter=new Waiter();
//点一份番茄炒蛋(命令),同时我们需要一位做番茄炒蛋的厨师(接受者)
Cook cook=new Cook();
FanQieChaoDan fqcd=new FanQieChaoDan(cook);
//顾客将番茄炒蛋的命令写进菜单交给服务员
waiter.setCommand(fqcd);
//服务员通知厨师开始炒菜
waiter.orderUp();
}
}
复制代码
从上面的代码中我们可以看到,命令对象(一道菜)通过在特定的接受者(厨师)绑定一组动作(cooking)来封装一个请求(execute),命令对象暴露给命令调用者的只有这个请求方法,命令调用者(服务员)根本不知道究竟是哪个接受者(厨师)做了哪些动作,只需要知道调用execute方法,该命令能完成即可。
命令模式一般还会有命令撤销,宏命令等功能。宏命令可以定义一个命令对象的数组,在宏命令对象中维持这个数组,执行execute方法时对数组中的命令依次调用其自身的execute方法即可,在此不展开。