一、定义

将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作.

我觉得可以这样:将一个请求封装为一个对象,对请求排队或记录请求日志,以及支持可撤销的操作;从而使你可用不同的请求对客户进行参数化;

二、实例:一个遥控面板,两台小家电。一个面板控制两台小家电

2.1  不用命令模式实现

命令发起者:一块遥控器

命令接收者:一堆小家电

小家电接口:

 public interface ISmallAppliance{int Appid { get; set; }void Open();void Off();}

电器:

public class Purifier : ISmallAppliance{public int Appid { get; set; }public Purifier(int appid){Appid = appid;Console.WriteLine("净化器: {0}", Appid);}public void Open(){Console.Write(" 启动【净化器】成功.");}public void Off(){Console.Write(" 关闭【净化器】成功.");}}public class Kettle : ISmallAppliance{public int Appid { get; set; }public Kettle(int appid){Appid = appid;Console.WriteLine("电水壶: {0}", Appid);}public void Open(){Console.Write(" 启动【电水壶】成功.");}public void Off(){Console.Write(" 关闭【电水壶】成功.");}}

遥控面板:

 public class CommandPannel{List<ISmallAppliance> apps = new List<ISmallAppliance>();        public void Sign(ISmallAppliance _sa){if (!apps.Contains(_sa))apps.Add(_sa);}public void OpenCommand(int appid){ISmallAppliance app = apps.Where(q => q.Appid == appid).FirstOrDefault();app.Open();}public void OffCommand(int appid){ISmallAppliance app = apps.Where(q => q.Appid == appid).FirstOrDefault();app.Off();}}

客户端:

            //客厅一台电水壶Command.ISmallAppliance kettle_1 = new Command.Kettle(1);//厨房一台电水壶Command.ISmallAppliance kettle_2 = new Command.Kettle(2);//卧室一台净化器Command.ISmallAppliance purifier_1 = new Command.Purifier(100);List<Command.ISmallAppliance> smallAppliances = new List<Command.ISmallAppliance>();smallAppliances.Add(kettle_1);smallAppliances.Add(kettle_2);smallAppliances.Add(purifier_1);//遥控器Command.CommandPannel cp = new Command.CommandPannel(smallAppliances);//打开:kettle_1cp.OpenCommand(kettle_1.Appid);//关闭:purifier_1cp.OffCommand(purifier_100.Appid);

由上可知:

命令的发出者—遥控面板 和 命令的接收者—注册的各个小家电.

命令发出者和命令接收者是紧耦合的:关闭和打开需要传递具体的电器ID。

---------------------------------------------------割----------------------------------------------------

2.2、命令模式实现

重温一下定义,其实每个设计模式的定义很重要,很多都限定了使用场景。

定义:将一个请求封装为一个对象,对请求排队或记录请求日志,以及支持可撤销的操作;从而使你可用不同的请求对客户进行参数化;

我们将定义分三个层次解读:

2.2.1  将一个请求封装为一个对象. 

即:我们将命令抽象,单独拿出来封装为对象。

也就是 命令模式 三大要素之一:  Command  (命令载体)

原来:遥控器有开按钮和关闭按钮。

 public class CommandPannel{List<ISmallAppliance> apps = new List<ISmallAppliance>();        public void Sign(ISmallAppliance _sa){if (!apps.Contains(_sa))apps.Add(_sa);}public void OpenCommand(int appid){ISmallAppliance app = apps.Where(q => q.Appid == appid).FirstOrDefault();app.Open();}public void OffCommand(int appid){ISmallAppliance app = apps.Where(q => q.Appid == appid).FirstOrDefault();app.Off();}}

现在:我们需要进行抽象,将命令抽象出来,像这样 :当然每个命令指定了执行者 protected SmallAppliance sa;这个合乎实际,每个命令肯定针对具体的电器。

 abstract public class Commands{protected SmallAppliance sa;public Commands(SmallAppliance _sa){sa = _sa;}abstract public void Do();}public class OpenCommand : Commands{public OpenCommand(SmallAppliance _sa) : base(_sa){}override public void Do(){sa.Open();}}public class OffCommand : Commands{public OffCommand(SmallAppliance _sa) : base(_sa){}override public void Do(){sa.Off();}}

2.2.2  对请求排队或记录请求日志,以及支持可撤销的操作

这是说的谁?遥控器 — 命令模式 三大要素之一:Invoker(请求处理者) 

不过现在的遥控器,要拥有下面三个功能:请求排队、记录日志、可撤销

public class Pannel{List<Commands> cmds = new List<Commands>();public Pannel(){Console.WriteLine("遥控器.");}public void Send(Commands cmd){//请求排队
            cmds.Add(cmd);//记录日志Console.WriteLine("发送命令时间 : {0}", DateTime.Now);}public void CancleCmd(Commands cmd){//可撤销
            cmds.Remove(cmd);//记录日志Console.WriteLine("取消命令时间 : {0}", DateTime.Now);}public void Execute(){if (cmds != null && cmds.Count > 0){foreach (var cmd in cmds){cmd.Do();}}}}

这就是我们改造之后的遥控器,简单粗暴的直接执行命令,不管谁的。来者不拒。

2.2.3 命令模式 三大要素之一:Receiver(接收者)

  abstract public class SmallAppliance{abstract public int ID { get; set; }abstract public void Open();abstract public void Off();}public class Purifier : SmallAppliance{public Purifier(int id){ID = id;Console.WriteLine("净化器: {0}", ID);}override public int ID { get; set; }override public void Open(){Console.Write(" 启动【净化器{0}】成功.", ID);}override public void Off(){Console.Write(" 关闭【净化器{0}】成功.", ID);}}public class Kettle : SmallAppliance{public Kettle(int id){ID = id;Console.WriteLine("电水壶: {0}", ID);}override public int ID { get; set; }override public void Open(){Console.Write(" 启动【电水壶{0}】成功.", ID);}override public void Off(){Console.Write(" 关闭【电水壶{0}】成功.", ID);}}

2.2.4  从而使你可用不同的请求对客户进行参数化

看看原来的客户端:打开和关闭没有好的办法进行统一传递参数,需要传递具体的电器的具体ID号

            //客厅一台电水壶Command.ISmallAppliance kettle_1 = new Command.Kettle(1);//厨房一台电水壶Command.ISmallAppliance kettle_2 = new Command.Kettle(2);//卧室一台净化器Command.ISmallAppliance purifier_1 = new Command.Purifier(100);List<Command.ISmallAppliance> smallAppliances = new List<Command.ISmallAppliance>();smallAppliances.Add(kettle_1);smallAppliances.Add(kettle_2);smallAppliances.Add(purifier_1);//遥控器Command.CommandPannel cp = new Command.CommandPannel(smallAppliances);//打开:kettle_1cp.OpenCommand(kettle_1.Appid);
            //关闭:purifier_1 cp.OffCommand(purifier_100.Appid);

再来看看现在:

            //Receiver(接收者):客厅一台电水壶Command.SmallAppliance kettle_1 = new Command.Kettle(1);//Receiver(接收者):厨房一台电水壶Command.SmallAppliance kettle_2 = new Command.Kettle(2);//Receiver(接收者):卧室一台净化器Command.SmallAppliance purifier_100 = new Command.Purifier(100);//Invoker(处理者)—遥控器Command.Pannel cp = new Command.Pannel();Command.OpenCommand cmd_open_k1 = new Command.OpenCommand(kettle_1);Command.OpenCommand cmd_open_p100 = new Command.OpenCommand(kettle_1);Command.OffCommand cmd_off_k1 = new Command.OffCommand(kettle_1);          Command.OffCommand cmd_off_p100 = new Command.OffCommand(kettle_1);            //发送命令
            cp.Send(cmd_open_k1);cp.Send(cmd_open_p100);cp.Send(cmd_off_k1);cp.CancleCmd(cmd_off_k1);cp.Send(cmd_off_p100);//执行命令cp.Execute();

 

三、总结

1、Recevier(接收者):最简单的接收者还是那些小家电,还是一样的味道.

2、Command(抽象命令): 将遥控器的的命令或者请求,抽象为Command(命令).【这是思想重要的转变】

3、Invoker(处理者):然后改造遥控器使之拥有三个核心功能:请求排队、记录日志、可撤销.【操作核心】

4、Client(客户端):就是我,我家里买了两台电水壶外加一台净化器,然后我快速的按着遥控器,嘀嘀,嘀嘀,嘀嘀,嘀嘀,嘀,TMD错了,撤销~~。然后喝水吃饭打豆豆

转载于:https://www.cnblogs.com/sunchong/p/5106513.html

设计模式(五):命令模式相关推荐

  1. 设计模式 之 命令模式

    2019独角兽企业重金招聘Python工程师标准>>> 设计模式 之 命令模式 命令模式比较简单,不过多赘述 为什么需要命令模式 将"行为请求者"与"行 ...

  2. 乐在其中设计模式(C#) - 命令模式(Command Pattern)

    原文:乐在其中设计模式(C#) - 命令模式(Command Pattern) [索引页] [源码下载] 乐在其中设计模式(C#) - 命令模式(Command Pattern) 作者:webabcd ...

  3. 「设计模式(五) - 代理模式」

    「设计模式(五) - 代理模式」 一.处处可见的"代理" "代理"在平常生活司空见惯,点外卖,租房子找中介,买飞机票等等.基本上用手机就能完成,也就是不直接接触 ...

  4. 23种设计模式之命令模式和策略模式的区别

    文章目录 概述 命令模式 策略模式 相同点 总结 概述 命令模式和策略模式确实很相似,只是命令模式多了一个接收者(Receiver)角色.它们虽然同为行为类模式,但是两者的区别还是很明显的.策略模式的 ...

  5. Android设计模式之——命令模式

    一.介绍 命令模式(Command Pattern),是行为型设计模式之一.命令模式相对于其他的设计模式来说并没有那么多的条条框框,其实它不是一个很"规范"的模式,不过,就是基于这 ...

  6. 一天学习一个设计模式之命令模式

    命令模式(Command),将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可撤销的操作. 代码如下: 1 /** 2 * 抽象命令角色类 3 */ ...

  7. java execute 执行成功_【JAVA】设计模式之命令模式(Command模式)的使用分析

    命令模式属于23种设计模式中行为模式中的一个,它也是一种简单实用非常普遍的设计模式. 首先看下GOF对命令模式的定义:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或记录 ...

  8. 设计模式之命令模式(行为型)

    目录 一.模式定义 二.模式角色 三.模式分析 四.典型例子 五.适用场景 一.模式定义 命令模式(Command Pattern):将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分离,两 ...

  9. 秒懂设计模式之命令模式(Command Pattern)

    [版权申明] 非商业目的注明出处可自由转载 博文地址:https://blog.csdn.net/ShuSheng0007/article/details/116115743 出自:shusheng0 ...

  10. 行为型设计模式(八)命令模式【王者荣耀的服务端实现】

    目录 一.概念及原理 二.具体实例 2.1 游戏开发背景知识 2.2 线程内轮询接收请求和处理请求实现 三.命令模式 VS 策略模式 四.小结 五.参考链接 一.概念及原理 命令模式的英文翻译是 Co ...

最新文章

  1. python获取图片像素矩阵_用python处理图片实现图像中的像素访问
  2. 2019清北学堂学习笔记
  3. intellij修改编辑器中的注释部分的颜色
  4. 才子佳人文学传统的戏拟与嘲仿
  5. php yii2 获取表里最大的id_Yii2中自带分页类实现分页
  6. 前端学习(1684):前端系列实战课程之判断游戏结束
  7. 最短路径——Dijkstra算法HDU Today(hdu2112)
  8. Linux的input输入子系统:设备驱动之按键驱动
  9. spark操作redis_Spark对接Redis快速入门
  10. Objective-C Runtime 运行时之一:类与对象
  11. 网页游戏开发秘笈 PDF扫描版
  12. 资源池、虚拟机、集群的关系
  13. 领导和同事嫌弃你的6个征兆,离失业不远了
  14. JS+html--实现图片轮播
  15. 数字逻辑电路——第四章 组合逻辑电路
  16. ip国家 数据库下载
  17. Genesis创世纪
  18. 在线任意进制转换工具
  19. Docker入门-什么是Docker
  20. 天津二级计算机考试地点,2016年9月天津计算机一级二级三级四级考点地址电话...

热门文章

  1. 第十五天 图【下】(大结局)
  2. 哟,2020年了!试着用vue做一个自己的小程序吧~~
  3. 分割字符串,字符串去除空格
  4. 实验三 编程、编译、连接、跟踪
  5. excel导入sqlserver数据库大数据量,可每秒控制数量
  6. Centos系统使用代理上网时 yum的代理设置
  7. C#基础(四)--值类型和引用类型,栈和堆的含义
  8. 2014/09/30 Learning Note
  9. 【转】新.Net开发必备工具详解之Snippet Compiler。
  10. 加快Vue项目的开发速度