【U3D日记-2016年9月2日】设计模式解决工作问题的一个实例
来源:互联网 发布:乐知英语的公司在哪 编辑:程序博客网 时间:2024/04/19 08:51
转眼间,在建哥这都干了半年了。
这半年算是我写代码最密集的半年吧,不官方,没套路,单纯的写代码。
不废话,今天遇到一个难题:
统一类型的商店,shop1,shop2,shop3. 在表现上,用同一种方式表现。客户端方面,自然统一处理了代码。
每一个商店对应一个配置表,也就是三张表,我们的导表工具会将它们导成三个类。我在这三个类中取数据,然后统一表现三个商店,于是有了这段代码:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace FictionFather{ class Program { static void Main( string [] args ) { string input = Console.ReadLine(); switch( input ) { case "1": ShopDay shopDay = new ShopDay(); Console.WriteLine(string.Format("Shop name is '{0}'", shopDay.name)); Console.WriteLine(string.Format("Use {0}th money", shopDay.priceType)); break; case "2": ShopWeek shopWeek = new ShopWeek(); Console.WriteLine(string.Format("Shop name is '{0}'", shopWeek.name)); Console.WriteLine(string.Format("Use {0}th money", shopWeek.priceType)); break; case "3": ShopMonth shopMonth = new ShopMonth(); Console.WriteLine(string.Format("Shop name is '{0}'", shopMonth.name)); Console.WriteLine(string.Format("Use {0}th money", shopMonth.priceType)); break; default: Console.WriteLine("only input 1,2 or 3"); break; } Console.ReadLine(); } } class ShopDay { public string name = "DayShop"; public int priceType = 2; } class ShopWeek { public string name = "WeekShop"; public int priceType = 200; } class ShopMonth{ public string name = "MonthShop"; public int priceType = 1001; }}vs控制台程序大概模拟一下
注意到没有,我在客户端用了switch,是哪个商店我就去哪个类取数据。你问我为什么不一起处理,这个我当时也是很苦恼,这三个商店类没有兄弟关系(没有共同继承一个父类),尽管他们结构是一样的,但是在语法上不能统一处理。说的有点啰嗦了,其实,本质原因是导表工具当初没有想到会有这种情况,不会套上父类,没有父类而我又不能加这才是最骚的。所以,我只能在客户端用switch。把相同的代码复制出很多份。并且每一个用到表的地方,我都要用一个switch。代码多不说,日后策划想加商店,我得把所有switch都加一个分支。我并不能保证我不会遗漏,麻烦又容易报错,真是哔了狗了。然后我又问策划:因为表的结构一致,可不可以将所有商店的数据配到一张表中,但这样其实我就是把策划给坑了。表的维护难度会大大提升不说,我也不能保证策划是否已经理解了这样配表的意义从而不犯错误。总之,这样不靠谱,人不能总为过去的事买单。于是我问了建哥,建哥说用反射,但是很冒险。
我想了一下反射,
这是用反射的实现过程,日后补充
总之,反射也不是很好,大材小用,而且影响了性能就更麻烦了
就在这时,一段代码以消息的方式出现在我电脑面前。代码末尾处写道:如果不嫌麻烦的话,可以试试这个。
好吧,说的跟黑客什么似的,其实就是有个人给我发QQ,这个人就是明李兄!
明李兄是我的前辈,也是我的校友。是一个思维很敏捷的人
我按照他的想法,将代码改成了:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace FictionFather{ class Program { static void Main( string [] args ) { string input = Console.ReadLine(); var shop = ShopManager.GetAShop((ShopType) ( int.Parse(input) )); if( shop != null ) { Console.WriteLine(string.Format("Better:Shop name is '{0}'", shop.name)); Console.WriteLine(string.Format("Better:Use {0}th money", shop.priceType)); } else { Console.WriteLine("only input 1,2 or 3"); } Console.ReadLine(); } } class ShopDay { public string name = "DayShop"; public int priceType = 2; } class ShopWeek { public string name = "WeekShop"; public int priceType = 200; } class ShopMonth{ public string name = "MonthShop"; public int priceType = 1001; } enum ShopType { ShopDay = 1, ShopWeek = 2, ShopMonth = 3 } class ShopBase { public virtual string name { get { return string.Empty; } } public virtual int priceType { get { return 0; } } } class ShopDayBox : ShopBase { ShopDay info = new ShopDay(); public override string name { get { return info.name; } } public override int priceType { get { return info.priceType; } } } class ShopWeekBox : ShopBase { ShopWeek info = new ShopWeek(); public override string name { get { return info.name; } } public override int priceType { get { return info.priceType; } } } class ShopMonthBox : ShopBase { ShopMonth info = new ShopMonth(); public override string name { get { return info.name; } } public override int priceType { get { return info.priceType; } } } class ShopManager { static public ShopBase GetAShop( ShopType type ) { switch( type ) { case ShopType.ShopDay: return new ShopDayBox(); case ShopType.ShopWeek: return new ShopWeekBox(); case ShopType.ShopMonth: return new ShopMonthBox(); } return null; } }}
是的,尽管付出了很多代价,但是我的客户端代码没有switch 了。 通过一个manager类管理,其实相当于强行用一个盒子包装,然后几个盒子有兄弟关系,根本问题得以解决。这样的好处是涉及的商店分子在manager添加一个即可, 而且box类如果写错也会被语法检测检查出来。省事,出错概率也很小。不过也许,还会有更好的设计模式。
我反思了一下,最近也看了很多设计模式相关的书《设计模式之禅》、《大话设计模式》等。也画了很多类图,写了很多小例子去理解。但是真正要用到它的时候却显得很无力,只能问别人。这种不能独立思考的状况我把它理解成是没有理解到问题的本质。其实我有一下不足:1语法知识不够坚固,应该多去了解每一个语法产生的意义。2项目实战较少。缺少百炼成钢的过程,以前我总追求效率,其实犯错也是成长的一个过程。
git地址:https://git.oschina.net/WebGL/FictionFather2.git 点击打开链接
- 【U3D日记-2016年9月2日】设计模式解决工作问题的一个实例
- 【U3D日记-2016年4月7日】入职一个月
- 【U3D日记-2016年10月9日】一道Codeforces引发的“代码整洁”思考
- 【U3D日记-2016年3月12日】NGUI初入——基本控件
- 【U3D日记-2016年10月28日】float转int 误差!
- =w=一个月的u3d学习纪念日记
- U3D学习笔记(2016年8月8日 )
- 工作日记—2005年12月28日
- 2006年7月6日 工作日记
- 2013年6月22日软件测试工作日记
- 工作日记——2015年6月16日
- 工作日记——2015年6月17日
- 工作日记——2015年6月19日
- 2017年4月20日 工作日记
- 2017年4月21日 工作日记
- 2017年4月22日 工作日记
- 2017 年 4月25日 工作日记
- 2017年4月27日 工作日记
- MSM8937平台bootloader调试之一
- Python 【Day2】
- Majority Element
- poj1742(多重背包dp)
- inent的用法
- 【U3D日记-2016年9月2日】设计模式解决工作问题的一个实例
- c++中定制输入输出操作
- TIJ读书笔记02-控制执行流程
- Input_poj1262_计算几何
- why what how???
- MD5加密
- 【noip2014】tyvj 4056飞扬的小鸟
- 封装
- 性能优化——内存优化(2)