小故事学设计模式之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 ...
随机推荐
- hdu1702 ACboy needs your help again!(栈处理)
ACboy needs your help again! Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K ( ...
- Yii框架 多表查询实例
Yii框架多表查询实例:总共分为两个步骤(以下的代码我全部都写在model中):1.先在主表model中声明关联表中所需要查询的字段. public $surveyls_description; // ...
- Beam概念学习系列之SDKs
不多说,直接上干货! https://beam.apache.org/get-started/beam-overview/ Beam SDK 提供了一个统一的编程模型,来处理任意规模的数据集,其中包括 ...
- SpringMvc上传文件遇到重复读取InputStream的问题
文件上传配置: <bean id="multipartResolver" class="org.springframework.web.multipart.comm ...
- TOJ 3651 确定比赛名次
描述 有N个比赛队(1<=N<=500),编号依次为1,2,3,....,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排 名,但现在裁判委员会不能直接获得每个队的比赛成绩 ...
- SVN创建资源库和远程连接配置
SVN创建资源库和远程连接配置 本机安装的是TortoiseSVN-1.7.5.22551-win32-svn-1.7.3.msi 安装好后会在鼠标右键中出现如图最后两项的选项: 创建svn资源库: ...
- Java学习第二十四天
1:多线程(理解) (1)JDK5以后的针对线程的锁定操作和释放操作 Lock锁 (2)死锁问题的描述和代码体现 (3)生产者和消费者多线程体现(线程间通信问题) 以学生作为资源来实现的 资源类:St ...
- 小程序中搜索文件,阅览pdf,分享文件链接,评论表情符号
小程序中搜索文件,阅览pdf,分享文件链接,评论表情符号 https://blog.csdn.net/hotqin888/article/details/84111389 小程序中打开网页和pdf h ...
- 使用waitfor 语句
aitfor语句用于延迟后面语句的执行,可以指定延迟时间长度是具体的时间.参考下面的语句: waitfor delay ’00:01:15’ print N’到时间了’ --也可以不加N 字符串 ...
- (转)vs2010 vs2013等vs中如何统计整个项目的代码行数
在一个大工程中有很多的源文件和头文件,我如何快速统计总行数? ------解决方案-------------------- b*[^:b#/]+.*$ ^b*[^:b#/]+.*$ ctrl + sh ...