系列文章

[Head First设计模式]山西面馆中的设计模式——装饰者模式

[Head First设计模式]山西面馆中的设计模式——观察者模式

[Head First设计模式]山西面馆中的设计模式——建造者模式

[Head First设计模式]饺子馆(冬至)中的设计模式——工厂模式

[Head First设计模式]一个人的平安夜——单例模式

[Head First设计模式]抢票中的设计模式——代理模式

[Head First设计模式]面向对象的3特征5原则

[Head First设计模式]鸭子模型——策略模式

[Head First设计模式]云南米线馆中的设计模式——模版方法模式

实例

这里采用书中餐厅订餐的例子。餐厅订餐的例子还是比较简单的,也比较好理解,书中的遥控器的例子,太长了,能把人绕晕,图1:

图2:

从餐厅到命令模式

命令模式类图

Command:
        定义命令的接口,声明执行的方法。
ConcreteCommand:
       具体的命令, 实现命令接口;通常会持有接收者,并调用接收者的功能来完成命令要执行的操作。
Receiver:
        接收者,真正执行命令的对象。任何类都可能成为一个接收者,只要它能够实现命令要求实现的相应功能。
Invoker:
        要求命令对象执行请求,通常会持有命令对象,可以持有很多的命令对象。这个是客户端真正触发命令并要求命令执行相应操作的地方,也就是说相当于使用命令对象的入口。
Client:
        创建具体的命令对象,并且设置命令对象的接收者。注意这个不是我们常规意义上的客户端,而是在组装命令对象和接收者,或许,把这个Client称为装配者会更好理解,因为真正使用命令的客户端是从Invoker来触发执行。

这里采用从实例到定义,倒着描述的方式,先从实例入手,有个大致印象,有助于理解。

命令模式定义

将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其它对象。命令模式也支持可撤销的操作。

实例代码实现

分析:帅哥顾客,土豪订单,美女服务员,资深大厨的角色是什么?

帅哥顾客:Client

土豪订单:实现Command接口的具体Command

美女服务员:Invoker

资深大厨:Receiver

代码实现:

Command接口

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace Wolfy.命令模式
{/// <summary>/// Command为所有命令声明一个接口,调用命令对象的excute方法/// 就可以让接收者进行相关的动作,/// </summary>public abstract class Command{public abstract void Execute();}
}

OrderCommand:具体的命令,继承自Command抽象类

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading;
 6 using System.Threading.Tasks;
 7
 8 namespace Wolfy.命令模式
 9 {
10     /// <summary>
11     /// 具体的命令
12     /// </summary>
13     public class OrderCommand : Command
14     {
15         /// <summary>
16         ///持有接受者对象
17         /// </summary>
18         SeniorChef receiver;
19         Order order;
20         public OrderCommand(SeniorChef receiver, Order order)
21         {
22             this.receiver = receiver;
23             this.order = order;
24         }
25         public override void Execute()
26         {
27
28             Console.WriteLine("{0}桌的订单:", order.DiningTable);
29             foreach (string item in order.FoodDic.Keys)
30             {
31                 //通常会转调接收者对象的相应方法,让接收者来真正执行功能
32                 receiver.MakeFood(order.FoodDic[item],item);
33             }
34             Thread.Sleep(2000);//停顿一下 模拟做饭的过程
35
36             Console.WriteLine("{0}桌的饭弄好了", order.DiningTable);
37         }
38     }
39 }

View Code

Waitor:Invoker调用者,seniorChef:接收者 厨师类

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace Wolfy.命令模式
{/// <summary>/// 美女服务员类 这里作为调用者Invoker的角色/// </summary>public class Waitor{ArrayList commands = null;//可以持有很多的命令对象public Waitor(){commands = new ArrayList();}public void SetCommand(Command cmd){commands.Add(cmd);}/// <summary>/// 提交订单 喊 订单来了,厨师开始执行/// </summary>public void OrderUp(){Console.WriteLine("美女服务员:叮咚,大厨,新订单来了.......");Console.WriteLine("资深厨师:收到");for (int i = 0; i < commands.Count; i++){Command cmd = commands[i] as Command;if (cmd != null){cmd.Execute();}}}}
}

Waitor

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6
 7 namespace Wolfy.命令模式
 8 {
 9     /// <summary>
10     /// 资深大厨类 是命令的Receiver
11     /// </summary>
12     public class SeniorChef
13     {
14         public void MakeFood(int num,string foodName)
15         {
16             Console.WriteLine("{0}份{1}", num,foodName);
17         }
18     }
19 }

SeniorChef

订单Order,封装订单内容,然后传入OrderCommand,将订单对象变为命令对象

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6
 7 namespace Wolfy.命令模式
 8 {
 9     /// <summary>
10     /// 订单
11     /// </summary>
12     public class Order
13     {
14         /// <summary>
15         /// 餐桌号码
16         /// </summary>
17         public int DiningTable { set; get; }
18         /// <summary>
19         /// food  key:饭名 value:多少份
20         /// </summary>
21         public Dictionary<string, int> FoodDic { set; get; }
22     }
23 }

Order

测试端Program相当于Client角色

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6
 7 namespace Wolfy.命令模式
 8 {
 9     class Program
10     {
11         static void Main(string[] args)
12         {
13             //program类 作为客户端
14             //创建2个order
15             Order order1 = new Order();
16             order1.DiningTable = 1;
17             order1.FoodDic = new Dictionary<string, int>() ;
18             order1.FoodDic.Add("西红柿鸡蛋面",1);
19             order1.FoodDic.Add("小杯可乐",2);
20
21             Order order2 = new Order();
22             order2.DiningTable = 3;
23             order2.FoodDic = new Dictionary<string, int>();
24             order2.FoodDic.Add("尖椒肉丝盖饭", 1);
25             order2.FoodDic.Add("小杯雪碧", 1);
26             //创建接收者
27             SeniorChef receiver=new SeniorChef();
28             //将订单这个两个消息封装成命令对象
29             OrderCommand cmd1 = new OrderCommand(receiver, order1);
30             OrderCommand cmd2 = new OrderCommand(receiver, order2);
31             //创建调用者 waitor
32             Waitor invoker = new Waitor();
33             //添加命令
34             invoker.SetCommand(cmd1);
35             invoker.SetCommand(cmd2);
36             //将订单带到柜台 并向厨师喊 订单来了
37             invoker.OrderUp();
38             Console.Read();
39         }
40     }
41 }

测试结果:

总结

命令模式优点:

1.降低对象之间的耦合度。
2.新的命令可以很容易地加入到系统中。
3.可以比较容易地设计一个组合命令。
4.调用同一方法实现不同的功能

缺点:

使用命令模式可能会导致某些系统有过多的具体命令类。因为针对每一个命令都需要设计一个具体命令类,因此某些系统可能需要大量具体命令类,这将影响命令模式的使用。

适用环境:

1.系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互。
2.系统需要在不同的时间指定请求、将请求排队和执行请求。
3.系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作。
4.系统需要将一组操作组合在一起,即支持宏命令。

今天在家研究了一天命令模式,以上为个人理解,如有不妥之处,请指出,一起交流学习,谢谢。

参考:

Head first 设计模式

百度百科

转载于:https://www.cnblogs.com/wolf-sun/p/3618911.html

[Head First设计模式]餐馆中的设计模式——命令模式相关推荐

  1. Java设计模式之行为型:命令模式

    前言: 在开发中,我们可能需要向某些对象发送一些请求,但我们不知道请求的具体接收者是谁,也不知道被请求的操作是哪个,只知道在系统运行中指定具体的请求接收者即可,打个比方,电视遥控器,我们只需知道按哪个 ...

  2. 设计模式自学笔记007_Real(命令模式、备忘录模式、桥接模式)

    设计模式自学笔记007_Real(命令模式.备忘录模式.桥接模式) 一.命令模式 在软件设计的过程中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道请求的操作是哪个.我们只需要 ...

  3. 设计模式(一):命令模式(2)——命令模式扩展之宏命令

    前言 命令模式的讲解分为四篇: 设计模式(一):命令模式(1)--基本的命令模式 设计模式(一):命令模式(2)--命令模式扩展之宏命令 设计模式(一):命令模式(3)--命令模式扩展之队列请求 设计 ...

  4. jdk中的设计模式_JDK中的设计模式

    jdk中的设计模式 Zen的JCG合作伙伴Brian Du Preez 是IT领域的合作伙伴, 在收集JDK中最常见的设计模式方面做得非常出色. 模式列表的确令人印象深刻且很长,因此让我们不再ba不休 ...

  5. 设计模式的C语言应用-命令模式-第五章

    模式介绍:命令模式(command) 命令模式的解释如下: 向对象发送一个请求,但是并不知道该请求的具体接收者是谁,具体的处理过程是如何的,只知道在程序运行中指定具体的请求接收者即可,对于这样将请求封 ...

  6. 设计模式笔记十五:命令模式

    原文:http://www.runoob.com/design-pattern/ 少许个人理解,如有错误请指出.欢迎一起讨论. 命令模式(Command Pattern) 是一种数据驱动的设计模式,它 ...

  7. 设计模式(十三): 命令模式

    命令模式 命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式.请求以命令的形式包裹在对象中,并传给调用对象.调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应 ...

  8. 小侃设计模式(十五)-命令模式

    1.概述 命令模式(Command Pattern)是将一个请求封装为一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能.它是行为型模式的一种,能 ...

  9. 围观设计模式(23)--行为型之命令模式(Command Pattern)

    在面向对象程式设计的范畴中,命令模式是一种设计模式,它尝试以物件来代表实际行动.命令物件可以把行动(action) 及其参数封装起来,于是这些行动可以被: 重复多次 取消(如果该物件有实作的话) 取消 ...

最新文章

  1. eclipse导入lombok后打不开(如果你的lombok不是最新的,那就来下载最新的)
  2. C++异常实现与longjmp, setjmp,栈指针EBP, Active Record
  3. 基于RESTful标准的Web Api
  4. [译]星际争霸人工智能比赛——规则
  5. 测试私有方法_Java基础之抽象类、接口作为方法参数和返回值
  6. 【转载】三极管,场效应管 工作原理小结
  7. android网络请求线程池,利用线程池实现Android客户端的http网络数据请求工具类
  8. 百度回应“宕机”;微信 5 年内出 VR 版?腾讯破解谷歌漏洞 | 极客头条
  9. matlab检测串口数据帧头,用matlab从串口读入数据产生图像进行分析遇到的问题,求大虾帮助!...
  10. linux 安装org2pg_Ora2Pg的安装和使用
  11. android 学习十四 探索安全性和权限
  12. paip.sql2k,sql2005,sql2008,sql2008 r2,SQL2012以及EXPRESS版本的区别
  13. 将html内容转换成word文档,一招教你将网页内容转化为word文档保存
  14. IT十大风云人物(转水冰洋)
  15. 计算机专业保研面试备考:概率论
  16. SQP 序列二次规划法
  17. Geoserver发布OSM官网地图
  18. Element UI-动态合并表格行
  19. 人工智能AI讲师NLP培训讲师叶梓:人工智能之最新NLP自然语言处理技术与实战-23
  20. win10下CUDA版本卸载与更新

热门文章

  1. 怎么让代码不再臃肿,写的像诗一样优雅
  2. Android开发——说说Adapter那点事
  3. jquery 读秒,倒数计时方案
  4. BeanShell中Getter和Setter语法
  5. Spring中的事务管理详解
  6. 关于SQL查询效率,100w数据,查询只要1秒
  7. 数据结构与算法试题集锦
  8. linux下安装redmine1.2.1全记录
  9. 2011年中国程序员薪水调查报告
  10. 浅谈Service Manager成为Android进程间通信(IPC)机制Binder守护进程之路(1)