设计模式学习005——命令模式

来源:互联网 发布:淘宝图像识别 编辑:程序博客网 时间:2024/05/03 00:22

       命令模式用来将“请求”封装成对象,然后用命令对象来参数化其他对象,而且也可以支持撤销操作。短短一句话,概括了命令模式的精髓下面讲解一下这句话中暗藏的原则:

第一:每个命令都是一个对象,本身有执行(exectue)和撤销(undo)两个方法,那个这个对象在执行和撤销执行方法,总得有个执行对象吧?没错,这个对象就是我们的执行者(接受者)(receiver)。也就是真是完成命令下达真实动作的那个对象,毋庸置疑,这个对象肯定是要付给命令对象本身的。这样一旦命令被执行,命令对象才能知道让那个对象去执行要做的事情。

第二:为什么说是使用命令对象来参数化其他对象呢?其实,我们这个很好理解。比方说,我们去餐厅吃饭,首先服务员会给我们一个菜单,我们完成点单(创造一个命令对象,菜单就是我们的命令对象),交给服务员(用菜单参数化了服务员,对应于setCommand()),服务员就是我们的调用者对象,然后服务员合适时候就会将菜单交给做菜的厨师窗口,厨师得到菜单(厨师就是我们的receiver),开始做菜(执行命令)。

下面我们就来模拟一下这个问题:

第一步:首选我们创造一个命令类,这是一个超类,所有的命令类都是其子类,它规定所有的命令类都必须有执行(exectue)和撤销执行(undo)这两个功能。

public interface Command {public void execute();public void undo();}
第二步:制造一个正式的命令子类

public class OrderCommand implements Command{public Chef chef;//创建命令的时候,就将这个命令到时候有谁来执行给指定好。public OrderCommand (Chef chef){this.chef = chef;}public void execute(){chef.doFood();}public void undo(){chef.undoFood();}}
第三步:把真正执行命令的对象(厨师)定义好,他完成命令真正要做的事情。

public class Chef {public void doFood(){System.out.println("我做了一道菜");}public void undoFood(){System.out.println("这道菜顾客不要了,我就不做了。");}}
第四步:定义我们的调用者对象。也就是我们的服务员对象

public class Servier {Command command ;Command preCommand;//这个命令用来记录最近一次执行的命令。public void setCommand(Command command){this.command = command;}public void startService(){command.execute();preCommand = command;}public void undoService(){preCommand.undo();}}
第五步:定义我们的客户对象。也就是客户端测试代码:

public class Client {//这个类就是客户,想到与产生命令(菜单)的人public static void main(String[] args) throws Exception{//产生一个菜单(命令),并指明这个菜单(命令)由谁完成Command orderCommand = new OrderCommand(new Chef());Servier servier = new Servier();//完成一个点单(产生一个命令)servier.setCommand(orderCommand);//将菜单给服务员。servier.startService();//服务员将菜单交到厨师台。Thread.sleep(5000);servier.undoService();//撤销服务。}}
到此为止,命令模式例子既可以完成。下面我们把其对应的UML表示出来,以便于理解。

想一下,消息队列如何实现?其实就是一个线程对象不断执行送过来的命令对象罢了,线程对象不断的从队列总取出要执行的命令,然后开始执行。仅此而已。

0 0