命令大家都不会陌生,那么在开始命令模式之前,可以想象一下生活中的命令模式的特点:

如老板命令你完成一个OA项目是一个命令,接着看看其特点:

1、在上面的命令中,命令的执行者肯定是聪明的你了。具体的执行方法,可能是通过vs实现,或者是通过eclipse实现,由此看来:命令要有个命令的执行者,还要有个命令的执行方法。

2、命令的发出者很明显是老板,老板还有个发出方法,可能是通过电话给你说,也可能给你邮件给你说,也可能是通过开会给你说。所以命令的发出者要有一个命令,还要有个发出的方法。

3、最后看看命令,命令有个名字,命令的肯定要执行。而且命令是在boss给你发出通知后执行的。

接下来看看命令模式的定义:

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

每次讲一个模式时,从定义都不能体会其中的技巧,所以接着我会通过举例子来说明命令模式。

二、命令模式的举例

下面来看看多用遥控器是如何使用命令模式的。

2.1需求

假设某个公司需要设计一个多用功能的遥控器。基本的需求如下:

该遥控器有可以控制风扇,白炽灯,热水器等等的多对开关,而且可能还有其他的电器,暂时不做其功能,但是希望可以保留接口,用的时间可以方便的扩展。

除上面的需求之外,还需要有个按钮,可以撤销上一步的操作。基本功能如下图:

命令模式(head first 设计模式5)

2.2问题

在设计遥控器时,风扇,白炽灯,热水器的开关方法已经定义好,其名字各不相同。不妨设置其方法为如下:

命令模式(head first 设计模式5)

由于各种电器的开关方法都不一样,而且还存在一个待扩展的电器,如果没有学习命名模式之前,我们在设置扩展的开关时,会出现的问题是什么呢?假设现在有电视,冰箱还可能会用到遥控器,那么我们会在最后一个开关上写if else,当然如果哪一天有多了一个大门也加入了我们的遥控的行列,这样我们继续加if else ,很显然随着电器的高速发展,会有多个需要遥控可以控制的。

举个例子,如果我们是需要遥控的客户,现在有一款遥控如果有遥控可以进行扩展,一种是可以扩展指定类型的,像上面的,只能再去扩展电视和冰箱中的一种,偶尔有一天你看到隔壁邻居的门,也可以使用遥控了,所以你去把你的高级遥控器,拿到扩展店时,扩展工程师说了,现在只能扩展电视和冰箱,不支持对大门的遥控扩展.

我们肯定是希望,可以自由的扩展,大门可以使用遥控了,就对大门扩展,车门使用遥控了,就对车门扩展……其实也就是一种松耦合的实现。

2.3分析问题

为了实现松耦合,我们现在来想一下,周末去请朋友吃饭,服务员mm问你吃什么,你说水煮活鱼,然后在菜单上面,写上水煮活鱼。下个星期天想吃花生米啤酒,同样也写在订单上,然后服务员mm把订单拿给厨师。

在上面的例子中,无论你点了什么菜,服务员mm,只需要知道顾客点的什么菜,从而给不同的厨师做(虽然不是直接的,但最终凉菜会给凉菜的师傅做,热菜的会给热菜的厨师做),然而具体的怎么做是厨师的事情,服务员知道顾客点上面菜,只是为了能正确的交个厨师去做。

其实在这个例子中,也是一个命令模式的例子,不同的订单对应的有不同的厨师,最终订单拿到厨师面前,就是对厨师下了个命令,要做菜了。每订单或者说是每种菜都对应着自己的厨师,所以,客服需要有订单的的引用,订单为了知道调用哪个厨师,需要有厨师引用;两个引用都是使用的组合。从而可以调用多种自己需要对象的方法来实现松耦合。这里记住:客服mm知道顾客点菜的目的是为了让不同的厨师去做。再直接一些就是为了使用不同的命令。

上面的吃饭问题和我们的遥控器问题差不多,都是包含下命令,命令的执行者,以及命令的具体内容。如果还是有些不清楚的话,就用简单的程序模拟一下上面的过程:

 1 class Program 
 2 { 
 3      static void Main(string[] args) 
 4      { 
 5          MM mm = new MM(); 
 6          //想吃热菜 
 7          mm.SetOrder(new ReCaiOrder()); 
 8          //mm还需要把菜单拿到厨师那里哦 
 9          mm.OnOrder(); 
10          //想吃凉菜 
11          mm.SetOrder(new LiangCaiOrder()); 
12          mm.OnOrder(); 
13          Console.ReadKey(); 
14      } 
15 }
16 
17 /// <summary> 
18 /// 订单 
19 /// </summary> 
20 interface IOrder 
21 { 
22      void Excute(); 
23 }
24 
25 /// <summary> 
26 /// 凉菜做法 
27 /// </summary> 
28 class LiangCaiChuShi 
29 { 
30      public void MakeCook() 
31      { 
32          Console.WriteLine("凉菜~!!!"); 
33      } 
34 } 
35 /// <summary> 
36 /// 凉菜订单 
37 /// </summary> 
38 class LiangCaiOrder:IOrder 
39 { 
40      LiangCaiChuShi chushi=new LiangCaiChuShi(); 
41      public void Excute() 
42      { 
43          chushi.MakeCook(); 
44      } 
45 } 
46 /// <summary> 
47 /// 热菜做法 
48 /// </summary> 
49 class ReCaiChuShi 
50 { 
51      public void Cook() 
52      { 
53          Console.WriteLine("热菜!!"); 
54      } 
55 }
56 
57 /// <summary> 
58 /// 热菜订单 
59 /// </summary> 
60 class ReCaiOrder : IOrder 
61 { 
62      ReCaiChuShi chushi=new ReCaiChuShi(); 
63      public void Excute() 
64      { 
65          chushi.Cook(); 
66      } 
67 } 
68 class MM 
69 { 
70      IOrder order; 
71      public void SetOrder(IOrder order) 
72      { 
73          this.order = order; 
74      } 
75      public void OnOrder() 
76      { 
77          order.Excute(); 
78      } 
79 } 
View Code

相关文章:

  • 2021-05-25
  • 2021-08-06
  • 2021-08-27
  • 2021-12-15
  • 2021-09-30
  • 2022-12-23
  • 2021-10-05
  • 2022-12-23
猜你喜欢
  • 2021-05-29
  • 2021-04-07
  • 2021-06-06
  • 2022-12-23
  • 2021-04-10
  • 2021-07-31
  • 2022-12-23
相关资源
相似解决方案