`
seaizon
  • 浏览: 138597 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

研磨设计模式之命令模式-4(转)

阅读更多

3.4  宏命令

        什么是宏命令呢?简单点说就是包含多个命令的命令,是一个命令的组合。举个例子来说吧,设想一下你去饭店吃饭的过程:
        (1)你走进一家饭店,找到座位坐下
        (2)服务员走过来,递给你菜谱
        (3)你开始点菜,服务员开始记录菜单,菜单是三联的,点菜完毕,服务员就会把菜单分成三份,一份给后厨,一份给收银台,一份保留备查。
        (4)点完菜,你坐在座位上等候,后厨会按照菜单做菜
        (5)每做好一份菜,就会由服务员送到你桌子上
        (6)然后你就可以大快朵颐了
        事实上,到饭店点餐是一个很典型的命令模式应用,作为客户的你,只需要发出命令,就是要吃什么菜,每道菜就相当于一个命令对象,服务员会在菜单上记录你点的菜,然后把菜单传递给后厨,后厨拿到菜单,会按照菜单进行饭菜制作,后厨就相当于接收者,是命令的真正执行者,厨师才知道每道菜具体怎么实现。
        在这个过程中,地位比较特殊的是服务员,在不考虑更复杂的管理,比如后厨管理的时候,负责命令和接收者的组装的就是服务员。比如你点了凉菜、热菜,你其实是不知道到底凉菜由谁来完成,热菜由谁来完成的,因此你只管发命令,而组装的工作就由服务员完成了,服务员知道凉菜送到凉菜部,那是已经做好的了,热菜才送到后厨,需要厨师现做,看起来服务员是一个组装者。
        同时呢,服务员还持有命令对象,也就是菜单,最后启动命令执行的也是服务员。因此,服务员就相当于标准命令模式中的Client和Invoker的融合。
        画个图来描述上述对应关系,如图6所示:



                                                   图6  点菜行为与命令模式对应示意图
1:宏命令在哪里?
        仔细观察上面的过程,再想想前面的命令模式的实现,看出点什么没有?
        前面实现的命令模式,都是客户端发出一个命令,然后马上就执行了这个命令,但是在上面的描述里面呢?是点一个菜,服务员就告诉厨师,然后厨师就开始做吗?很明显不是的,服务员会一直等,等到你点完菜,当你说“点完了”的时候,服务员才会启动命令的执行,请注意,这个时候执行的就不是一个命令了,而是执行一堆命令。
        描述这一堆命令的就是菜单,如果把菜单也抽象成为一个命令,就相当于一个大的命令,当客户说“点完了”的时候,就相当于触发这个大的命令,意思就是执行菜单这个命令就可以了,这个菜单命令包含多个命令对象,一个命令对象就相当于一道菜。
        那么这个菜单就相当于我们说的宏命令。
2:如何实现宏命令
        宏命令从本质上讲类似于一个命令,基本上把它当命令对象进行处理。但是它跟普通的命令对象又有些不一样,就是宏命令包含有多个普通的命令对象,执行一个宏命令,简单点说,就是执行宏命令里面所包含的所有命令对象,有点打包执行的意味。
(1)先来定义接收者,就是厨师的接口和实现,先看接口,示例代码如下:

Java代码 
  1. /** 
  2.  * 厨师的接口 
  3.  */  
  4. public interface CookApi {  
  5.     /** 
  6.      * 示意,做菜的方法 
  7.      * @param name 菜名 
  8.      */  
  9.     public void cook(String name);  
  10. }  

 

厨师又分成两类,一类是做热菜的师傅,一类是做凉菜的师傅,先看看做热菜的厨师的实现示意,示例代码如下:

Java代码 
  1. /** 
  2.  * 厨师对象,做热菜 
  3.  */  
  4. public class HotCook implements CookApi{  
  5.     public void cook(String name) {  
  6.         System.out.println("本厨师正在做:"+name);  
  7.     }  
  8. }  

 

做凉菜的师傅,示例代码如下:

Java代码 
  1. /** 
  2.  * 厨师对象,做凉菜 
  3.  */  
  4. public class CoolCook implements CookApi {  
  5.     public void cook(String name) {  
  6.         System.out.println("凉菜"+name+"已经做好,本厨师正在装盘。" );  
  7.     }  
  8. }  

 

(2)接下来,来定义命令接口,跟以前一样,示例代码如下:

Java代码 
  1. /** 
  2.  * 命令接口,声明执行的操作 
  3.  */  
  4. public interface Command {  
  5.     /** 
  6.      * 执行命令对应的操作 
  7.      */  
  8.     public void execute();  
  9. }  

 

(3)定义好了命令的接口,该来具体实现命令了。
        实现方式跟以前一样,持有接收者,当执行命令的时候,转调接收者,让接收者去真正实现功能,这里的接收者就是厨师。 
        这里实现命令的时候,跟标准的命令模式的命令实现有一点不同,标准的命令模式的命令实现的时候,是通过构造方法传入接收者对象,这里改成了使用setter的方式来设置接收者对象,也就是说可以动态的切换接收者对象,而无须重新构建对象。
        示例中定义了三道菜,分别是两道热菜:北京烤鸭、绿豆排骨煲,一道凉菜:蒜泥白肉,三个具体的实现类非常类似,只是菜名不同,为了节省篇幅,这里就只看一个命令对象的具体实现。代码示例如下:

Java代码 
  1. /** 
  2.  * 命令对象,绿豆排骨煲 
  3.  */  
  4. public class ChopCommand implements Command{  
  5.     /** 
  6.      * 持有具体做菜的厨师的对象 
  7.      */  
  8.     private CookApi cookApi = null;  
  9.     /** 
  10.      * 设置具体做菜的厨师的对象 
  11.      * @param cookApi 具体做菜的厨师的对象 
  12.      */  
  13.     public void setCookApi(CookApi cookApi) {  
  14.         this.cookApi = cookApi;  
  15.     }  
  16.   
  17.     public void execute() {  
  18.         this.cookApi.cook("绿豆排骨煲");  
  19.     }  
  20. }  

 

(4)该来组合菜单对象了,也就是宏命令对象。

  • 首先宏命令就其本质还是一个命令,所以一样要实现Command接口
  • 其次宏命令跟普通命令的不同在于:宏命令是多个命令组合起来的,因此在宏命令对象里面会记录多个组成它的命令对象
  • 第三,既然是包含多个命令对象,得有方法让这多个命令对象能被组合进来
  • 第四,既然宏命令包含了多个命令对象,执行宏命令对象就相当于依次执行这些命令对象,也就是循环执行这些命令对象

     看看代码示例会更清晰些,代码示例如下:

Java代码 
  1. /** 
  2.  * 菜单对象,是个宏命令对象 
  3.  */  
  4. public class MenuCommand implements Command {  
  5.     /** 
  6.      * 用来记录组合本菜单的多道菜品,也就是多个命令对象 
  7.      */  
  8.     private Collection<Command> col = new ArrayList<Command>();  
  9.     /** 
  10.      * 点菜,把菜品加入到菜单中 
  11.      * @param cmd 客户点的菜 
  12.      */  
  13.     public void addCommand(Command cmd){  
  14.         col.add(cmd);  
  15.     }  
  16.     public void execute() {  
  17.         //执行菜单其实就是循环执行菜单里面的每个菜  
  18.         for(Command cmd : col){  
  19.             cmd.execute();  
  20.         }  
  21.     }  
  22. }  

 (5)该服务员类重磅登场了,它实现的功能,相当于标准命令模式实现中的Client加上Invoker,前面都是文字讲述,看看代码如何实现,示例代码如下:

Java代码 
  1. /** 
  2.  * 服务员,负责组合菜单,负责组装每个菜和具体的实现者, 
  3.  * 还负责执行调用,相当于标准Command模式的Client+Invoker 
  4.  */  
  5. public class Waiter {  
  6.     /** 
  7.      * 持有一个宏命令对象——菜单 
  8.      */  
  9.     private MenuCommand menuCommand = new MenuCommand();  
  10.     /** 
  11.      * 客户点菜 
  12.      * @param cmd 客户点的菜,每道菜是一个命令对象 
  13.      */  
  14.     public void orderDish(Command cmd){  
  15.         //客户传过来的命令对象是没有和接收者组装的  
  16.         //在这里组装吧  
  17.         CookApi hotCook = new HotCook();  
  18.         CookApi coolCook = new CoolCook();  
  19.         //判读到底是组合凉菜师傅还是热菜师傅  
  20.         //简单点根据命令的原始对象的类型来判断  
  21.         if(cmd instanceof DuckCommand){  
  22.             ((DuckCommand)cmd).setCookApi(hotCook);  
  23.         }else if(cmd instanceof ChopCommand){  
  24.             ((ChopCommand)cmd).setCookApi(hotCook);  
  25.         }else if(cmd instanceof PorkCommand){  
  26.             //这是个凉菜,所以要组合凉菜的师傅  
  27.             ((PorkCommand)cmd).setCookApi(coolCook);  
  28.         }  
  29.         //添加到菜单中  
  30.         menuCommand.addCommand(cmd);  
  31.     }  
  32.     /** 
  33. font-s
    分享到:
    评论

相关推荐

    研磨设计模式(完整带书签).part2.pdf

    《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...

    研磨设计模式-part4

    《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...

    研磨设计模式--chjavach的博客文章

    单例模式、工厂方法模式、策略模式、命令模式和桥接模式。

    研磨设计模式(完整带书签).part1.pdf

    《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...

    研磨设计模式-part2

    《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...

    研磨设计模式-part3

    《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...

    研磨设计模式.part4(共4个)

    《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...

    研磨设计模式.part3(共4个)

    《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...

    研磨设计模式.part2(共4个)

    《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...

    研磨设计模式.part1(共4个)

    《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...

    研磨设计模式.docx

    研磨设计模式系列,包括: 单例模式、工厂方法模式、策略模式、命令模式和桥接模式

    研磨设计模式之命令模式

    命令模式也是开发中常见的一个模式,也不是太难,比较简单,下面来详细的写一下命令模式。命令模式(Command)1 场景问题 1.1 如何开机计有些朋友看到这个标题会非常奇怪,电脑装配好了,如何开机?不就是按下启动按钮...

    javaee笔试题-bodhi-publish:一花一世界,一叶一菩提

    学习研磨设计模式,记录项目的速查目录,方便查询对应模式的具体实现方式。 四、数据库 五、操作系统  基础核心概念、常用命令使用 六、网络 HTTP请求响应、持久连接、会话跟踪、跨站攻击 HTTPS工作过程、TLS证书...

Global site tag (gtag.js) - Google Analytics