• 2010-11-07

    代码之丑(四)

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://www.blogbus.com/dreamhead-logs/82703006.html

    这是一个找茬的游戏,下面三段代码的差别在哪:
      if ( 1 == SignRunToInsert)    {
        RetList->Insert(i, NewCatalog);
      } else {
        RetList->Add(NewCatalog);
      }

      if ( 1 == SignRunToInsert)    {
        RetList->Insert(m, NewCatalog);
      } else {
        RetList->Add(NewCatalog);
      }

      if ( 1 == SignRunToInsert)    {
        RetList->Insert(j, NewPrivNode);
      } else {
        RetList->Add(NewPrivNode);
      }

    答案时间:除了用到变量之外,完全相同。我想说的是,这是我从一个文件的一次diff中看到的。

    不妨设想一下修改这些代码时的情形:费尽九牛二虎之力,我终于找到该在哪改动代码,改了。作为一个有职业操守的程序员,我知道别的地方也需要类似的修改。于是,趁人不备,把刚做修改拷贝了一份,放到另外需要修改的地方。修改了几个变量,编译通过了。世界应该就此清净,至少问题解决了。

    好吧!虽然这个程序员有职业操守的程序员,却缺少了些职业技能,至少在挥舞“拷贝粘贴”时,他没有嗅到散发出的臭味。

    只要意识到坏味道,修改是件很容易的事,提出一个新函数即可:
      void AddNode(List& RetList, int SignRunToInsert, int Pos, Node& Node) {
        if ( 1 == SignRunToInsert)    {
          RetList->Insert(Pos, Node);
        } else {
          RetList->Add(Node);
        }
      }

    于是,原来那三段代码变成了三个调用:
      AddNode(RetList, SignRunToInsert, i, NewCatalog);
      AddNode(RetList, SignRunToInsert, m, NewCatalog);
      AddNode(RetList, SignRunToInsert, j, NewPrivNode);

    当然,这种修改只是一个局部的微调,如果有更多的上下文信息,我们可以做得更好。

    重复,是最为常见的坏味道。上面这种重复实际上是非常容易发现的,也是很容易修改。但所有这一切的前提是,发现坏味道。

    长时间生活在这种代码里面,我们会对坏味道失去嗅觉。更可怕的是,一个初来乍到的嗅觉尚灵敏的人意识到这个问题,那些失去嗅觉的人却告诫他,别乱动,这挺好。

    趁嗅觉尚在,请坚持代码正义。


    本文已经首发于InfoQ中文站 ,版权所有,原文为《专栏:代码之丑(四) 》,如需转载,请务必附带本声明,谢谢。

    InfoQ中文站 是一个面向中高端技术人员的在线独立社区,为Java、.NET、Ruby、SOA、敏捷、架构等领域提供及时而有深度的资讯、高端技术大会如QCon 、免费迷你书下载如《架构师 》等。

    分享到:

    历史上的今天:

    引用地址:

    评论

  • 好东西,学习代码。
  • if vyltclb='1' or vyltclb='2' or vyltclb='3' then
    uo_client.resetvar()
    vsqlstr="select count(*) vcount"+&
    " from md.patient_info a,"+&
  • 如果调用在不同的Assabmly中的话,
    写成公共的函数也许是件十分困难的事情
  • 那些失去嗅觉的人却告诫他,别乱动,这挺好。
    在没有单元测试的事务脚本业务逻辑层中,还是别动为好.
  • to Serval:
    应该相信你的编译器,现代编译器已经可以做出很好的优化了
  • 封裝到函数里会不会产生额外的开销?
    回复Serval说:
    性能是一个永远的借口。按照这种说法,就不该用任何函数,所有的代码都平铺在那里好了。封装函数是迈向干净代码的第一步,只有封装小函数,更多的重复才会暴露出来。
    2010-11-17 06:53:12
  • 质量,尤其是代码质量,是敏捷的源头...
    但是,很多时候,应用要看团队的人的意识,这个是最大的问题!
    非常同意最后一段话,我之前一直跟TEAM的人说,你如果连续2年一直在写很SHIT的代码,无论你之前如何的所谓优秀,2年后,你不会再知道好代码应该长成什么样子的。
    每天改进一点点,其实就是敏捷的意识!