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 : (一) 在永和豆浆店的更多相关文章

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

    (IT的事就是过场多,过场多了就容易忘,所以我们不妨看一个记一个,这也是一个办法,顺便还能跟同行们交流一下)  要和老婆一起回老家了, 成都离我们安徽太远, 两个人飞一下过去就要花掉近三千块, 于是我 ...

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

    老婆有一件蓝色的裙子和一件粉色的裙子, 不管怎么穿,她还是原来的老婆. 但是在软件里就不一定了, 如果把老婆比作一个class的话, 有一种做法是会因为增加了两个新的Property而继承出两个子类: ...

  3. 生活沉思录 via 哲理小故事

    本文转载:http://www.cnblogs.com/willick/p/3174803.html 1.小托蒂的悲剧 意大利小男孩托蒂,有一只十分奇怪的眼睛,因为从生理上看,这是一只完全正常的眼睛, ...

  4. 从零开始单排学设计模式「装饰模式」黑铁 I

    阅读本文大概需要 3.6 分钟. 本篇是设计模式系列的第四篇,虽然之前也写过相应的文章,但是因为种种原因后来断掉了,而且发现之前写的内容也很渣,不够系统. 所以现在打算重写,加上距离现在也有一段时间了 ...

  5. 杂谈---小故事小道理,面试中的小技巧(NO.2)

    本篇是接着上一篇面试随笔的,上一次有猿友反应写的有些“扯淡”,LZ思来想去最大的原因可能是由于上一章写的全是一些大忌,既然是大忌,那么在现实当中发生的概率还是相对较小的,大部分人还是很少在面试中犯如此 ...

  6. 从壹开始 [ Design Pattern ] 之三 ║ 工厂模式 与 小故事

    编者按: 定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法使得一个类的实例化延迟到子类. 工厂模式,是迄今为止,使用最多,最广泛的设计模式之一,它的身影几乎出现在每一个框架和个人代码之中 ...

  7. 有趣 GIF 动图集 - 仿佛每张小动图都诉说了一个小笑话或者小故事

    点这里 来自法国南特(Nantes)的 Guillaume Kurkdjian 目前还是个学生.Kurkdjian 擅长创作一些平面动态图像,这些有趣的小动图仿佛每张都诉说了一个小笑话或者小故事,像个 ...

  8. Swift语言 1小时速学教程

    本文由 张渊杰 (网名寂静)编写 Swift语言 1小时速学教程 写在前面的话 有些人可能想, 呵呵, 1小时学一门语言, 你不是搞笑吧, 我想说, 是的, 完全可以, 就要看你怎么学了 要想在1小时 ...

  9. 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 ...

随机推荐

  1. ndoejs解析req,伪造http请求

    require("./m3m4") var http = require('http'); var server = http.createServer(); server.lis ...

  2. HDU 2879 数论

    HeHe Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submis ...

  3. PIE SDK符号选择器

    1. 功能简介 符号选择器可以根据不同的需求进行改变图层的符号形状以及颜色,下面基于PIE SDK介绍如何使用符号选择器. 2. 功能实现说明 2.1.  实现思路及原理说明 第一步 加载图层 第二步 ...

  4. CAPL编程实现诊断刷写,车联网FOTA流程自动化测试(代码篇)

    原创内容,转载请注明出处   接上篇,本文主要讲CAPL编程详细实现,软件环境CANoe  11.0 一.Simulation Setup 1.建模之前,首先创建一个.DBC文件.如果不会,可以用一个 ...

  5. Kibana修改Time日志格式

    选择左侧management 打开Advanced Settings 编辑:dateFormat,默认格式是:MMMM Do YYYY, HH:mm:ss.SSS,修改为:YYYY-MM-DD HH: ...

  6. TOJ 2749 Absent Substrings

    描述 Given a string of symbols, it’s natural to look it over and see what substrings are present. In t ...

  7. TOJ 2711 Stars

    描述 Astronomers often examine star maps where stars are represented by points on a plane and each sta ...

  8. 在NuoDB上运行Asterisk

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文来自云+社区翻译社,作者Hans362 您可能已经熟悉Asterisk,一个广泛部署的开源Telephony框架.如果你不太熟悉,你应该 ...

  9. this 显示绑定

    function foo (el) { console.log(el, this.id); } var obj = { id: 'aaa' }; [2,6,3].forEach(foo, obj); ...

  10. Hashtable元素的遍历

    遍历用到DictionaryEntry(字典键/值对) 实例 创建一个Hashtable对象,向其中添加4个元素,然后遍历 static void Main(string[] args) { Hash ...