订餐系统之组合捜索

  每每遇到多条件搜索商家时,总要编写一大堆“闻者伤心,见者流泪”的代码,而且不同条件代码还不能通用,终于痛定思痛,“重构”了所有代码,虽不能全部通用,倒也是进步了些。特以此文,怀念下那些“白费”的时光,也希望借此让有经验的同学们指点一二!

  先上两张图,一看就明白了:

      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;
    }
    。。。
View Code

 

偷懒后的代码

  坑就在那里,只增不减,我们便一而再,再而三的扑通,直到北京某订餐网站时,得到的需求:“筛选项目现在不太确定,可能会变”。这样的需求开始让我思考了:继续原来的方案,直接上手,不过以后不是自己骂自己,就是别人骂自己;亦或是重构之前的代码,付出时间的代价,但是以后不是自己受益,就是别人的受益。似乎,不用怎么权衡,于是开始偷懒之路了。

  首先,之前每个筛选项目编写不同的方法生成对应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;
    }
View Code

  不知道大家有注意到多选择的搜索没,如图中餐厅服务、场地类型、场地特色等,多选择后,查询语句的写法不知您们是怎么写的。我也是根据订餐小秘书的参数值猜出一种方法:每个项目的值都是2n ,后台保存时,保存了所有选择项目的和,前台查询时sql 语句的写法为:

  SqlWhere += " and  (MyService & " + mystatus+" > 0)";

结语

  之前有个需求:为数据库中每个备注为空的字段添加备注为“扩展字段”,在企业管理器中处理了50张表后,才发现一条sql 语句就可完成,还好,后面还剩100张表呢!

  之前有个需求:把excel 中的表结构,生成到数据库中,当时纳闷了,对方为什么不直接提供sql 语句。纳闷完了,还得继续操作,慢慢的加完一张表,确认几次保证字段没错后,忍无可忍才发现用PowerDesigner+一个vb 脚本就可以生成表。

  。。。

  文章总会有结束的时候,但是偷懒之路永无止境!

      成为一名优秀的程序员!

  

posted @ 2013-11-02 09:09  2J  阅读(2118)  评论(15编辑  收藏  举报