小故事学设计模式之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!

时间: 2024-10-07 16:39:07

小故事学设计模式之Command : (一) 在永和豆浆店的相关文章

小故事学设计模式之Decorate: (二)老婆的新衣服

老婆有一件蓝色的裙子和一件粉色的裙子, 不管怎么穿,她还是原来的老婆. 但是在软件里就不一定了, 如果把老婆比作一个class的话, 有一种做法是会因为增加了两个新的Property而继承出两个子类: "穿裙子的老婆, 穿粉色上衣的老婆". 你这样弄出两个子类也没什么不对, 问题是当MM的有上百件服装的时候,就会产生上百个子类,这个不好,将来万一父类一变化,下面上百个子类都要一个个地去修改,太乱了. 有一个更合理的方式来解决这个"老婆的装饰问题".我们的要求是:  

小故事学设计模式之Observer : (三) 老婆帮忙订机票

(IT的事就是过场多,过场多了就容易忘,所以我们不妨看一个记一个,这也是一个办法,顺便还能跟同行们交流一下)  要和老婆一起回老家了, 成都离我们安徽太远, 两个人飞一下过去就要花掉近三千块, 于是我们决定找找有没有更便宜的机票, "你帮我找找吧, 如果找到的话,跟我说一下",我说道. "行!"老婆记住了这事. 很快我得到通知, 南航有更便宜的, 580块. 这是一个简单的observer模式. 什么是observer? 其定义如下: The Observer Pa

圈子内小故事

咱也学学马未都先生,没有真相,只是残存一个道理. 恩,这句话还真是有点道理,那下面这些小故事就是告诉我们,在程序的世界里,行胜于言. ------------------------------------------- 著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处.作者:Eugene Hsueh链接:http://www.zhihu.com/question/20355709/answer/14873547来源:知乎 是的,马克·扎克伯格独自完成了 Facebook 第一

70个晨会激励哲理小故事

  1.面对生命的态度  有位太太请了个油漆匠到家里粉刷墙壁.  油漆匠一走进门,看到她的丈夫双目失明,顿时流露出怜悯的眼光.可是男主人一向开朗乐观,所以油漆匠在那里工作了几天,他们谈得很投机:油漆匠也从未提起男主人的缺憾.  工作完毕,油漆匠取出帐单,那位太太发现比谈妥的价钱打了一个很大的折扣.  她问油漆匠:“怎么少算这么多呢?”  油漆匠回答说:“我跟你先生在一起觉得很快乐,他对人生的态度,使我觉得自己的境况还不算最坏.所以减去的那一部分,算是我对他表示一点谢意,因为他使我不会把工作看的太

励志小故事:再努力一点点

美国寻金热的时代,吸引了成千上万做黄金梦的人.有些人不惜变卖自己的全部家财,离乡背井,跑到美国去淘金. 有一个异乡人,也把自己在英国家乡的田地卖掉了,只身跑到美国最热门淘金的地方,希望能找到金矿后衣锦还乡. 他首先在当地买了一间屋作栖身之所,安顿之后,便开始他的寻金旅程,每天早出晚归,非常辛苦地到处找寻金矿.开始的时候,他还是满怀希望,相信很快便能找到金矿.可是,日复一日,年复一年,他从一个壮健的中年人,渐渐变成一个老年人,他找寻金矿的事业还是毫无进展. 最后,到他临死的时候,他的寻金梦终于成为

第一篇博客(python爬取小故事网并写入mysql)

前言: 这是一篇来自整理EVERNOTE的笔记所产生的小博客,实现功能主要为用广度优先算法爬取小故事网,爬满100个链接并写入mysql,虽然CS作为双学位已经修习了三年多了,但不仅理论知识一般,动手能力也很差,在学习的空余时间前前后后DEBUG了很多次,下面给出源代码及所遇到的BUG. 本博客参照代码及PROJECT来源:http://kexue.fm/archives/4385/ 源代码: 1 import requests as rq 2 import re 3 import codecs

来自大数据的反思:需要你读懂的10个小故事

摘要:随着各种技术发展,很多人都在吹捧大数据.然而如同股市一样,越是高涨,越是需要警醒,在大数据热火朝天前行的路上,多一点反思,多一份冷静,或许能让这路走的更好.更远.本文的10个小故事,或许能让你有所得. 自2011年以来,大数据旋风以"迅雷不及掩耳之势"席卷中国.毋庸置疑,大数据已然成为继云计算.物联网之后新一轮的技术变革热潮,不仅是信息领域,经济.政治.社会等诸多领域都"磨刀霍霍"向大数据,准备在其中逐得一席之地. 中国工程院李国杰院士更是把大数据提升到战略的

关于JavaScript的小故事

妈妈:Netscape公司 原名:LiveScript 更名原因:想沾Java的光 亲缘关系:取了一个叫JavaScript的名字,其实和Java没什么血缘关系 关于JavaScript的小故事,布布扣,bubuko.com

看到的一个小故事-回车和换行的区别

          在计算机还没有出现之前,有一种叫做电传打字机(Teletype Model 33)的玩意,每秒钟可以打10个字符.但是它有一个问题,就是打完一行换行的时候,要用去0.2秒,正好可以打两个字符.要是在这0.2秒里面,又有新的字符传过来,那么这个字符将丢失.   于是,研制人员想了个办法解决这个问题,就是在每行后面加两个表示结束的字符.一个叫做"回车",告诉打字机把打印头定位在左边界:另一个叫做"换行",告诉打字机把纸向下移一行.   这就是&quo