设计模式是C#程序员从拖控件成长为技术大牛的必经之路,经过《Head First》洗礼后,作为一个随笔留在博客园吧。
OK,让我们进行第一任务:请朋友喝茶或者喝咖啡。
整理下我们的思路:喝茶或者喝咖啡,都要煮开水、洗杯子、冲泡茶(咖啡)。煮开水和洗杯子代码可以复用,考虑这个原则(实现代码的复用选择抽象类,实现多态性选择接口),我们选择创建一个抽象类,用来实现煮开水和洗杯子功能。
代码如下:
1usingSystem;23namespaceSimpleDrinkFactory4{5abstractclassBeforeDrink6{7//煮开水8publicvoidBoilWater()9{10Console.WriteLine("煮开水");11}12//洗杯子13publicvoidWashCup()14{15Console.WriteLine("洗杯子");16}17//冲泡(子类继承重写)18publicabstractvoidFunction();19}20}
BeforeDrink
1usingSystem;23namespaceSimpleDrinkFactory4{5classTea:BeforeDrink6{7publicoverridevoidFunction()8{9Console.WriteLine("冲泡茶叶");10//throw new NotImplementedException();11}12}13}
Tea
1usingSystem;23namespaceSimpleDrinkFactory4{5classCoffee:BeforeDrink6{7publicoverridevoidFunction()8{9Console.WriteLine("冲泡咖啡");10//throw new NotImplementedException();11}12}13}
Coffee
1usingSystem;23namespaceSimpleDrinkFactory4{5classPRogram6{7staticvoidMain(string[] args)8{9Console.WriteLine("星期天,朋友来我家玩,我请大家和饮料。");10Console.WriteLine("请选择要喝的饮料:Tea or Coffee");11stringtype =Console.ReadLine();12BeforeDrink drink =null;13switch(type)14{15case"Tea":16drink=newTea();17
break;18case"Coffee":19drink =newCoffee();20
break;21default:22Console.WriteLine("Sorry,没有您选择的饮料");23
break;24}25drink.BoilWater();26drink.WashCup();27drink.Function();28Console.WriteLine("朋友喝"+ type +"");29Console.WriteLine("朋友满意的走了");30Console.ReadKey();31}32}33}
Main()
执行之后应该是下图所示
过了一段时间,岳父来我家做客,点名只喝温酒。
岳父发话了,咋办,赶紧按照下面流程重新修改咱们的Drink程序呗:
1、添加alcohol类,继承于BeforeDrink,重写Function方法
2、修改Main()中的Switch方法,添加alcohol分支
OK,经过修改,岳父可以喝温酒了。但是岳母来了,点名要喝红糖水;父亲来了,点名要喝。。。
然后大家就会发现,维护起来太麻烦了,同时我们的Switch也会越来也多分支。
这个时候,终于要用到我们的工厂模式了。
看下简单工厂模式的UML图(UML不会用,见谅)
按照上述UML图写我们的代码。
Tea、Coffee、BeforeDrink类和上面一样没有变化,新增SimpleDrinkFactory类和修改Main();
1namespaceSimpleDrinkFactory2{3classSimpleDrinkFactory4{5publicstaticBeforeDrink CreatDrink(stringtype)6{7BeforeDrink drink =null;8if(type.Equals("Tea"))9{10drink =newTea();11}12elseif(type.Equals("Coffee"))13{14drink =newCoffee();15}16returndrink;17}18}19}
SimpleDrinkFactory
1usingSystem;23namespaceSimpleDrinkFactory4{5classProgram6{7staticvoidMain(string[] args)8{9Console.WriteLine("星期天,朋友来我家玩,我请大家和饮料。");10Console.WriteLine("请输入要喝的饮料:");11stringtype =Console.ReadLine();12BeforeDrink sdf =SimpleDrinkFactory.CreatDrink(type);13sdf.BoilWater();14sdf.WashCup();15sdf.Function();16//switch (type)17//{18//case"Tea":19//drink=new Tea();20//
break;21//case "Coffee":22//drink = new Coffee();23//
break;24//default:25//Console.WriteLine("Sorry,没有您选择的饮料");26//
break;27//}28//drink.BoilWater();29//drink.WashCup();30//drink.Function();31Console.WriteLine("朋友喝"+ type +"");32Console.WriteLine("朋友满意的走了");33Console.ReadKey();34}35}36}
Main()
执行之后的结果如下
从代码上看,其实变化的部分只是将Main()中的代码Copy至新增的SimpleDrinkFactory类中。
但这恰恰是面向对象设计的一个很关键的思路。(还记得封装、继承、多态么)
在以后的日记里,咱们会遇到更简单的方法,可以让我们的代码自动创建不同的实例,不用每次新增一个饮料,都要重新修改Switch或者if语句。
Ps:古语道,世界上最难的唯有两件事,一为将别人的钱财装进自己的口袋里,二为将自己的思想塞入别人的脑袋中。古人诚不欺我。