每每遇到多条件搜索商家时,总要编写一大堆“闻者伤心,见者流泪”的代码,而且不同条件代码还不能通用,终于痛定思痛,“重构”了所有代码,虽不能全部通用,倒也是进步了些。特以此文,怀念下那些“白费”的时光,也希望借此让有经验的同学们指点一二!
先上两张图,一看就明白了:
1.下图中根据多种条件(有的可以多选)来搜索商家。
2.下图中根据多种条件(有的可以多选)来搜索商家。
我想,这样的需求应该是常伴大家左右吧。对于我们做点餐网站的来说,更是每个系统都避免不了,搜索条件还不同,每个都是一大堆重复、难以维护的代码。一个不喜欢偷懒的程序员不是个好程序员,为了成为一个好程序员,于是开始了偷懒历程。
由于每个筛选项目,及选中的条件都要根据当前条件来生成相应的链接,当时年轻,于是有了下面的代码,如果要增加一个筛选项目,这个改动将是巨大的,因为每个筛选项目的方法都要修改。按理:加个筛选项目是一个简单的需求,但是我们面对这样简单的需求变化时,却是这样的措手不及、狼狈不堪!如果是他人来维护这个代码时,第一句话一定是:前人挖坑,后人扑通!当然,我相信大部分优秀的程序员都是在这周而复始的“挖坑-扑通”的过程中历练出来的。
/// <summary> /// 生成区域标签URL /// </summary> /// <param name="bid"></param> /// <param name="id"></param> /// <returns></returns> protected string getsectionUrl(object id) { string url = "FindEat.aspx?a=1"; if (id.ToString() != "0") { url += "&sid=" + id; } if (HjNetHelper.GetQueryString("keyword") != "") { url += "&keyword=" + Request["keyword"]; } if (HjNetHelper.GetQueryString("mid") != "") { url += "&mid=" + Request["mid"]; } if (HjNetHelper.GetQueryString("typeid") != "") { url += "&typeid=" + Request["typeid"]; } if (HjNetHelper.GetQueryString("on") != "") { url += "&on=" + Request["on"]; } if (HjNetHelper.GetQueryString("ot") != "") { url += "&ot=" + Request["ot"]; } if (HjNetHelper.GetQueryString("sortid") != "") { url += "&sortid=" + Request["sortid"]; } if (HjNetHelper.GetQueryString("subsortid") != "") { url += "&subsortid=" + Request["subsortid"]; } if (HjNetHelper.GetQueryString("rem") != "") { url += "&rem=" + Request["rem"]; } return url; } /// <summary> /// 生成特色标签URL /// </summary> /// <param name="bid"></param> /// <param name="id"></param> /// <returns></returns> protected string getwantUrl(object id) { string url = "FindEat.aspx?a=1"; if (id.ToString() != "0") { url += "&mid=" + id; } if (HjNetHelper.GetQueryString("id") != "") { url += "&id=" + Request["id"]; } if (HjNetHelper.GetQueryString("keyword") != "") { url += "&keyword=" + Request["keyword"]; } if (HjNetHelper.GetQueryString("sid") != "") { url += "&sid=" + Request["sid"]; } if (HjNetHelper.GetQueryString("typeid") != "") { url += "&typeid=" + Request["typeid"]; } if (HjNetHelper.GetQueryString("on") != "") { url += "&on=" + Request["on"]; } if (HjNetHelper.GetQueryString("ot") != "") { url += "&ot=" + Request["ot"]; } if (HjNetHelper.GetQueryString("sortid") != "") { url += "&sortid=" + Request["sortid"]; } if (HjNetHelper.GetQueryString("subsortid") != "") { url += "&subsortid=" + Request["subsortid"]; } if (HjNetHelper.GetQueryString("rem") != "") { url += "&rem=" + Request["rem"]; } return url; } 。。。
坑就在那里,只增不减,我们便一而再,再而三的扑通,直到北京某订餐网站时,得到的需求:“筛选项目现在不太确定,可能会变”。这样的需求开始让我思考了:继续原来的方案,直接上手,不过以后不是自己骂自己,就是别人骂自己;亦或是重构之前的代码,付出时间的代价,但是以后不是自己受益,就是别人的受益。似乎,不用怎么权衡,于是开始偷懒之路了。
首先,之前每个筛选项目编写不同的方法生成对应URL,是因为参数不确定,于是,声明一个变量Dictionary<string, string> mypara 保存所有参数(键,值对),参数以这样的形式出现searchshop.aspx?para1=sp304/s299/r644/a312/
再通过伪静态生成这样的链接:http://localhost:801/search/sp304/s299/r644/a312/ 【这是客户想看到有形式,我也只是根据订餐小秘书的形式,变向实现了】
有了前面的基础,生成筛选项目的链接及删除某条件的链接,方法就统一了。虽然根据条件生成查询条件的代码量没有变化,当然,这部分代码也不能有通用的,但是生成相应URL的方法从原来的N变成了1,增加一个筛选项目时,变化的代码也只是增量部分。我想很多看到这里的同学会说,这是一个很简单的处理方案,应该是第一时间想到的,并对此噗之以鼻,当然,简单的东西,想到就是理所当然,没相到就是一脸茫然,就如知道按重起键和会按重起键的差距是999美元一样。
/// <summary> /// 获取每个链接的url /// </summary> /// <param name="tag"></param> /// <param name="id"></param> /// <param name="depth">1表示第一级,2表示第二级,...</param> /// <returns></returns> protected string GetMyUrl(string tag, object id, int depth) { string url = "weddingsearch.aspx?para1="; foreach (var item in mypara) { if (item.Key != tag) { url += item.Key + item.Value + "/"; } } url += tag + id + "/"; return url; } /// <summary> /// 获取每个链接的url(已经选择的条件那里使用,传入的参数表示要删除的) /// </summary> /// <param name="tag">要删除标签</param> /// <returns></returns> protected string deleteTag(string tag) { string url = "weddingsearch.aspx?para1="; foreach (var item in mypara) { if (item.Key != tag) { url += item.Key + item.Value + "/"; } } return url; }
不知道大家有注意到多选择的搜索没,如图中餐厅服务、场地类型、场地特色等,多选择后,查询语句的写法不知您们是怎么写的。我也是根据订餐小秘书的参数值猜出一种方法:每个项目的值都是2n ,后台保存时,保存了所有选择项目的和,前台查询时sql 语句的写法为:
SqlWhere += " and (MyService & " + mystatus+" > 0)";
之前有个需求:为数据库中每个备注为空的字段添加备注为“扩展字段”,在企业管理器中处理了50张表后,才发现一条sql 语句就可完成,还好,后面还剩100张表呢!
之前有个需求:把excel 中的表结构,生成到数据库中,当时纳闷了,对方为什么不直接提供sql 语句。纳闷完了,还得继续操作,慢慢的加完一张表,确认几次保证字段没错后,忍无可忍才发现用PowerDesigner+一个vb 脚本就可以生成表。
。。。
文章总会有结束的时候,但是偷懒之路永无止境!
成为一名优秀的程序员!