小故事学设计模式之Command : (一) 在永和豆浆店
IT的事就是过场多,过场多了就容易忘,所以我们不妨看一个记一个,这也是一个办法,顺便跟同行们学习交流一下)
前几天出去拍照,饿到腿软, 回城附近有一家永和豆浆店, 我们决定去那边解决午餐.
豆浆店里面还不错, 整得挺时尚的, (跟我几年前在杭州去的那家区别蛮大).我喜欢餐馆里明亮的色调和鲜翠欲滴的菜品照片.
服务员也不错, 挺和气的.
邻桌饭菜的香气弥漫开来,像卡通片一样飘过来, 罩着点菜的我们俩和面前可爱的服务员(三个大头娃娃!).
服务员熟练地询问,打字, 然后把小票传给后面厨房的小窗里. 一回头又面对下一位顾客了.
真是职业化! 我赞叹不已.
让我想起软件设计中的command模式.
!永和豆浆店的Command模式!
command模式我也背不下来定义,但是目的我还是知道的, 就是为了让不同的人专心做好自己的事, 以达到高效率完成一个任务的目的.
这里作为客人的我俩, 只专心挑选自己喜欢的饭菜, 其他的我不用操心.
作为服务员, 她只管专心在电脑中录入我们点的菜名, 然后把小票传给厨房, 至于菜里放多少盐,根本也不是她份内的事,所以她也用不着烦心.
而厨子的任务就是按单做菜.(这里我没有写厨子,只是为了简单起见)
用软件的术语讲, 为了达到command模式的目的, 我们要防止类和类之间过于耦合, 让它们之间的消息传递尽量简洁明确.
public interface ICustomer
{
string Name
{
get;
}
}
public class FeiFei:ICustomer
{
private string _name;
public string Name
{
get{ return _name;}
set { _name = value;}
} public FeiFei(string n)
{
_name = n;
}
} public class Neo:ICustomer
{
private string _name;
public string Name
{
get{ return _name;}
set { _name = value;}
} public Neo(string n)
{
_name = n;
}
}
public class Waitress
{
Order _o;
public Waitress(Order o)
{
_o = o;
OrderUp();
} private void OrderUp()
{
StringBuilder sb = new StringBuilder();
foreach(ICustomer c in _o.Customer)
{
sb.Append(c.Name+" , ");
} string mycustomer = sb.ToString();
StringBuilder pc = new StringBuilder(); foreach (String p in _o.Packages)
{
pc.Append(p+" , ");
} string mypackage = pc.ToString(); Console.WriteLine(mycustomer + "You picked " + pc );
Console.WriteLine("Please find a place there, thanks!");
}
} public class Order
{
private IList<string> _packages = new List<string>();
private IList<ICustomer> _customers = new List<ICustomer>(); public IList<string> Packages
{
get { return _packages; }
} public IList<ICustomer> Customers
{
get { return _customers; }
}
}
好的, 下面的镜头:
主要演员: neo, feifei, 服务员
情景 : (参见代码中的说明)
[TestFixture]
public class PlaceOrder
{
[Test]
public void Place()
{
ICustomer feifei = new FeiFei("Feifei");//neo进店
ICustomer neo = new FeiFei("Neo");//feifei进店 Order o = new Order();//上菜单 o.Customers.Add(neo);
o.Packages.Add("Package A");//neo点了套餐A o.Customers.Add(feifei);
o.Packages.Add("Package B");//feifei点了套餐B Waitress w = new Waitress(o); //镜头切换到服务员mm那儿,我们把要点的套餐告诉了她,mm在电脑中录入后,礼貌地让我们找个地方先坐坐(场景详见Waitrees类代码)
w.OrderUp();
}
}
ok,我们来运行一下, 服务员小姐在打出小票后说:
Neo, Feifei, you picked Package A, Package B,
Please find a place there, thanks!
这时你可能在想, 那如果客人有其他需要,希望得到服务员的帮助怎么办?以软件设计的术语来说就是, open for adding, close for modification.
唔... ...有道理, 那我们就在原有的设计上再增加这些服务, 下面我来说明一下:
以客人要求提供下面两项服务为例:
1. 要求服务员帮他们带到满意的座位上去.
2. 要求服务员帮他们指引一下洗手间的位置.
我们要做到,以后任何新的职责增加和减少给这个服务员,都不要老去修改服务员员这个类.(要不,服务员是不是很累, 人家很忙的, 你变来变去的, 人家会弄混掉的.)
所以我们增加了一个接口IService, 并派生出两个类 LeadToToilet和LeadToTable, 以后再有什么其他的新职责, 都从这个接口中以类的形式派生出来.
public interface IService
{
void Execute();
} public class LeadToToilet:IService
{
public void Execute()
{
console.WriteLine("Go along the row of tables, and turn left at the end, there lies the toilet!");
}
} public class LeadToTable:IService
{
public void Execute()
{
console.WriteLine("You might need a no-smoking area, so come with me please!");
}
}
而服务员类中, 我们只要增加一个方法SupplyService()就可以了.
public void SupplyService(IService _s)
{
_s.Execute();
}
OK, 接下来看一下新的场景:
主要演员: 服务员
情景 : 客人想找一个无烟座位, 服务员带他们过去; 客人又想上洗手间, 服务员亲切地给他指路.
[TestFixture]
public class PlaceOrder
{
[Test]
public void Place()
{
ICustomer feifei = new FeiFei("Feifei");//neo进店
ICustomer neo = new FeiFei("Neo");//feifei进店 Waitress w = new Waitress(o); //服务员mm来了 IService WhereShallWeSit = new LeadToTable(); //坐哪里呢
w.SupplyService(WhereShallWeSit);//服务员给我们指导座位 IService WhereIsToilet = new LeadToToilet(); //要上洗手间了
w.SupplyService(WhereIsToilet);//服务员带我过去 }
}
执行这段代码, 让我们听听服务员小姐亲切的声音和职业化的素质吧:
You might need a no-smoking area, so come with me please!
Go along the row of tables, and turn left at the end, there lies the toilet!
完
小故事学设计模式之Command : (一) 在永和豆浆店的更多相关文章
- 小故事学设计模式之Observer : (三) 老婆帮忙订机票
(IT的事就是过场多,过场多了就容易忘,所以我们不妨看一个记一个,这也是一个办法,顺便还能跟同行们交流一下) 要和老婆一起回老家了, 成都离我们安徽太远, 两个人飞一下过去就要花掉近三千块, 于是我 ...
- 小故事学设计模式之Decorate: (二)老婆的新衣服
老婆有一件蓝色的裙子和一件粉色的裙子, 不管怎么穿,她还是原来的老婆. 但是在软件里就不一定了, 如果把老婆比作一个class的话, 有一种做法是会因为增加了两个新的Property而继承出两个子类: ...
- 生活沉思录 via 哲理小故事
本文转载:http://www.cnblogs.com/willick/p/3174803.html 1.小托蒂的悲剧 意大利小男孩托蒂,有一只十分奇怪的眼睛,因为从生理上看,这是一只完全正常的眼睛, ...
- 从零开始单排学设计模式「装饰模式」黑铁 I
阅读本文大概需要 3.6 分钟. 本篇是设计模式系列的第四篇,虽然之前也写过相应的文章,但是因为种种原因后来断掉了,而且发现之前写的内容也很渣,不够系统. 所以现在打算重写,加上距离现在也有一段时间了 ...
- 杂谈---小故事小道理,面试中的小技巧(NO.2)
本篇是接着上一篇面试随笔的,上一次有猿友反应写的有些“扯淡”,LZ思来想去最大的原因可能是由于上一章写的全是一些大忌,既然是大忌,那么在现实当中发生的概率还是相对较小的,大部分人还是很少在面试中犯如此 ...
- 从壹开始 [ Design Pattern ] 之三 ║ 工厂模式 与 小故事
编者按: 定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法使得一个类的实例化延迟到子类. 工厂模式,是迄今为止,使用最多,最广泛的设计模式之一,它的身影几乎出现在每一个框架和个人代码之中 ...
- 有趣 GIF 动图集 - 仿佛每张小动图都诉说了一个小笑话或者小故事
点这里 来自法国南特(Nantes)的 Guillaume Kurkdjian 目前还是个学生.Kurkdjian 擅长创作一些平面动态图像,这些有趣的小动图仿佛每张都诉说了一个小笑话或者小故事,像个 ...
- Swift语言 1小时速学教程
本文由 张渊杰 (网名寂静)编写 Swift语言 1小时速学教程 写在前面的话 有些人可能想, 呵呵, 1小时学一门语言, 你不是搞笑吧, 我想说, 是的, 完全可以, 就要看你怎么学了 要想在1小时 ...
- UESTC_小panpan学图论 2015 UESTC Training for Graph Theory<Problem J>
J - 小panpan学图论 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) S ...
随机推荐
- PIE SDK图像旋转
1.算法功能简介 图像旋转可使图像以中心点为轴沿特定方向旋转指定的角度. PIESDK支持算法功能的执行,下面对图像旋转算法功能进行介绍. 2.算法功能实现说明 2.1 实现步骤 第一步 算法参数设置 ...
- 请求网络图片缓存到本地 ,还有一些现成的图片加载框架的使用 Ace网络篇(一)
现在去买年货~~~~~~ 占坑, 现在来填坑 填完睡觉,感谢这俩月的把自己往死里逼得奋斗从JAVA什么都不懂到现在,做这些也是给在自学路上的新人(我也是菜鸟)一点点我力所能及的帮助,等我水平更高了还会 ...
- Android 开发手记一NDK编程实例
在Android上,应用程序的开发,大部分基于Java语言来实现.要使用c或是c++的程序或库,就需要使用NDK来实现.NDK是Native Development Kit的简称.它是一个工具集,集成 ...
- java中static方法的继承性
首先需要知道的是,java中所有的public实例方法都默认是virtual的,static方法不是virtual的,所以static方法可以被覆盖(new),但不可被重写(override) 1.被 ...
- jqgrid 操作
1.获取单个id 获取行号,有这种方式: var rowid = $("#gridList").jqGrid("getGridParam", "sel ...
- <meta http-equiv="X-UA-Compatible" content="IE=edge" />详解
X-UA-Compatible是针对IE8新加的一个设置,对于IE8之外的浏览器是不识别的,这个区别与content="IE=7"在无论页面是否包含<!DOCTYPE> ...
- setInterval()的三种写法
前言: setInterval("fun()",time)有两个参数:fun()为要执行的函数:time为多久执行一次函数,单位是毫秒: 我们做一个简单的例子,就是每隔5s弹出一个 ...
- Oracle JDBC 连接卡死后 Connection Reset
坑 这绝对是我碰计算机以来遇到的第一大坑! 症状: 在Linux主机上远程登录,执行一个简单的Oracle的JDBC连接程序(jar包),结果硬生生的卡在了连接建立验证阶段,然后等上几分钟后因为连接超 ...
- P2085 最小函数值(minval)
题目描述 有n个函数,分别为F1,F2,...,Fn.定义Fi(x)=Aix^2+Bix+Ci (x∈N*).给定这些Ai.Bi和Ci,请求出所有函数的所有函数值中最小的m个(如有重复的要输出多个). ...
- Python中变量的本质探索
Python中变量的本质探索 参考:Vamei博客Python进阶09 动态类型 ''' a = [1,2,3] ''' (1)这条"赋值语句"实际上是将a指向对象"[1 ...