小故事学设计模式之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. 功能简介 栅格数据分级渲染是根据不同的分级规则,对像元值进行等级划分:并通过对每一级设置不同的显示符号和标注信息,从而达到分级显示的效果. 2.功能实现说明 2.1. 实现思路及原理说明 第一 ... 
- TT 安装之 Windwos
			WINDOWS在 控制面板-〉管理工具-〉本地安全策略-〉本地策略-〉用户权限分配-〉锁定内存页-〉添加用户或组-〉高级查找 然后确定 然后安装 (WINDOWS在 控制面板-〉管理工具-〉ODBC工 ... 
- SpringCloud---服务治理---Spring Cloud Eureka
			1.概述 1.1 Spring Cloud Eureka是Spring Cloud Netflix微服务套件中的一部分,基于Netflix Eureka做了二次封装,主要负责完成微服务架构中的服务治理 ... 
- 3.CAS原子操作
			什么是原子性操作,按照官方的解析:原子操作不能在一个中间操作中停止,要么全部成功要么全部失败.(An atomic action cannot stop in the middle: it eithe ... 
- mysql 数据存储引擎区别
			一,存储类型 二 , MyISAM默认存储引擎 MyISAM 管理非事务表.是ISAM 的扩展格式.除了提供ISAM里所没有的索引的字段管理等的大量功能.MyISAM 还使用一种表格锁定的机制.来优化 ... 
- 【JAVA】重载和重写的区别
			重写(Overriding) 重写规则 1. 参数列表:必须与被重写方法的参数列表完全匹配. 2. 返回类型:必须与超类中被重写的方法中声明的返回类型或子类型完全相同 3. 访问级别:一定不能比被 ... 
- Linux分区扩容
			lz在MAC上面使用Linux虚拟机,开始只建了一个分区,挂载在”/”目录下.现在硬盘空间不够了,所以lz就来给这个分区扩容. 首先,当然是要给虚拟机分配更多的硬盘空间喽(lz用的是VMware Fu ... 
- 命令行编译java项目
			命令行编译java项目 项目名: testproj 目录 src -> cn -> busix -> test bin lib 编译项目 cd testproj javac -d . ... 
- nginx 导致文件上传中途中断 Failed to load resource: net::ERR_CONNECTION_RESET
			昨天上传文件出了问题,常常在进度条到一半的时候就终止了.在本地测试的时候倒是没问题,今天早上用花生壳换了另一个域名,在我本地和服务器都测试,却能够上传文件成功.然后就想到了可能是nginx的问题,也在 ... 
- python实现查询的数据写入到excel
			#coding=utf-8import sysimport xlwtimport pymysql as MySQLdb #这里是python3 如果你是python2.x的话,import MySQL ... 
