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点了套餐Ao.Customers.Add(feifei);
o.Packages.Add("Package B");//feifei点了套餐BWaitress 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!
完