[Head First设计模式]山西面馆中的设计模式——装饰者模式html
[Head First设计模式]山西面馆中的设计模式——观察者模式设计模式
[Head First设计模式]山西面馆中的设计模式——建造者模式ide
[Head First设计模式]饺子馆(冬至)中的设计模式——工厂模式post
[Head First设计模式]一我的的平安夜——单例模式学习
[Head First设计模式]抢票中的设计模式——代理模式测试
[Head First设计模式]面向对象的3特征5原则this
[Head First设计模式]云南米线馆中的设计模式——模版方法模式spa
这里采用书中餐厅订餐的例子。餐厅订餐的例子仍是比较简单的,也比较好理解,书中的遥控器的例子,太长了,能把人绕晕,图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 }
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(); } } } } }
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 }
订单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 }
测试端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 设计模式
百度百科