分享让人折服的优秀代码基因

1 背景

近来参与一个较大团队的项目实施,项目的金额几千万,人数近百。但是,项目实施后,暴露出以下几个问题:

(1)质量不佳,团队成员水平参差不齐,软件外部质量、内部质量一致性差;

(2)需求不确定,时间非常紧,代码频繁修改,越来越丑,效率变低。

为了保证项目按时按质交付,质量改善刻不容缓。因此,在项目的初中期开始,做了以下三件事情:

(1)制定统一的界面规范,制定了统一参考实例,为所有成员进行定期界面规范的培训和评审;

(2)制定统一的代码规范,制定了《评审文化构建》、《代码之丑》PPT,培养团队的质量文化和评审文化,实施评审;

(3)引入管理工具ReviewBoard。

项目统一构建了标准、规范,有效保证了界面的一致性,但是代码质量的提高却不是那么简单的事情。在这里,我暂不分享项目的情况,未来会通过更加详细的文章来介绍标准、规范化软件开发方法对于项目的重要性。

2 ReviewBoard介绍

这里倒是引出了一款优秀工具ReviewBoard。这款工具简单易用,功能强大。通过
它来实施代码评审非常有效。代码评审分为提交前评审(Pre-Review)和提交后评审(Post-Review)两种方式。提交前评审,即开发人员代

码变更后,需要提交到ReviewBoard,经过评审通过后,才能提交到SVN源码服务器,如果没有通过评审,则代码提交会失败,一行都无法提交;提交

后评审,即开发人员先提交代码,然后再提交变更到ReviewBoard,如果评审未通过,则修改代码,更新评审直到通过为止。这两种方式,各有优劣,我
们采用的是后一种,它不阻塞开发人员提交代码,无法100%控制所有质量,但是可以达到80%以上。

ReviewBoard设计之初更多考虑的是支持Pre-Review方式,因此,存在
以下问题:(1)提交通过后,Review无法自动进行状态变更为关闭,会与所有通过评审的ReviewRequest混在一起;(2)无法看出未通过评
审的请求进行再次更新,因为如果再次更新后,意味着要进行第二次评审。在管理过程中,会查询哪些请求没有通过评审,定期给开发人员发送通知。

因此,我决定对ReviewBoard进行订制来支持以上功能。不
过,ReviewBoard是基于Python语言和基于Django框架开发,我从来没有学习过Python,更没有学习过Django,那如何来修
改?所以,我开始对ReviewBoard做研究。ReviewBoard最新版本只能在非Windows运行,我在Ubuntu
14.04安装部署,同时使用MySQL数据库。因此,我开始来尝试做修改。

3 尝试修改ReviewBoard

3.1 探索第一步:数据库

首先,研究数据库,惊讶发现其数据库设计非常的整齐,压根不需要查看任何文档即可知道数
据库的表、字段的意义。我找到了几个关键的表,分别是reviews_reviewrequest,看看其字段,与界面显示几乎一致,一下子就明白什么意

思,顺着字段意思,找到了另外的两个关键表diffviewer_diffsethistory、diffviewer_diffset。查询一下这些表
的数据,我很容易来解决第一个问题,通过一条SQL语句即可将通过评审的ReviewRequest关闭,这样就不需要查看到这些评审请求了。

3.2 学习Python并修改代码

接下来的第二个问题,需要修改代码,我花了3个小时学习了Python,通过在线的英文帮助,直接在控制台做实验,学习基本语法结构、学习类与对象编程、学习了Python模块与编译,对Python初步熟悉之后,我决定开始来进行代码修改。

因此,我先通过相似列“Submitter”对所有文件进行查询,通过它很快找到了
columns.py和grids.py这两个文件,看了代码之后,发现ReviewBoard的评审请求通过这两个文件来实现,进行再次查询名称没有再

发现关联文件了。通过这两个文件,可以发现,columns.py用于定义要显示的所有的列,grids.py进行列的组合和显示。那么接下来可以简单的
进行模仿添加一个列了。该列定义为Diffs。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

class DiffSetCountColumn(Column):

    """Shows the diff set count of published reviews for a review request."""

    def __init__(self, *args, **kwargs):

        super(DiffSetCountColumn, self).__init__(

            label=_('Diffs'),

            detailed_label=_('Number of Diffs'),

            shrink=True,

            sortable=True,

            link=False,

            *kwargs, **kwargs)

    def render_data(self, state, review_request):

        if review_request.mydiffsetcount > 1:

            return ('<span class="issue-count">'

                    ' <span class="issue-icon">!</span> %s'

                    '</span>'

                    % review_request.mydiffsetcount)

        else:

            return ''

    def augment_queryset(self, state, queryset):

        return queryset.extra(select={

            'mydiffsetcount': """

                SELECT COUNT(*)

                  FROM diffviewer_diffset

                  WHERE diffviewer_diffset.history_id =

                        reviews_reviewrequest.diffset_history_id

            """

        })

简单说明一下,我定
义了DiffSetCountColumn类,继承于Column类,类初始化方法为__init__,相当于构造器。这里的self是以前经常使用的
this,定义了两个方法,一个是augment_queryset,用于当前列的数据显示,定义名称为mydiffsetcount,另外定义一个方法
render_data,即在表格中展现数据。这里参考了其它列定义。

接下来在grids.py中声明对该列的使用,非常简单。

25行新增:

DiffSetCountColumn,

99行新增:

diffset_count = DiffSetCountColumn()

接着重启Apache服务器,可以简单测试,惊讶发现可以工作了。

3.3 再进一步添加功能

有了这次尝试,我接下来想再进一步来定制。目前各个小组提交到不同的SVN地址,通过SVN可以区分各个组提交情况。但是ReviewBoard没有针对SVN地址的过滤。

首先修改columns.py,修改Repository列。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

class RepositoryColumn(Column):

    """Shows the name of the repository the review request's change is on."""

    def __init__(self, *args, **kwargs):

        super(RepositoryColumn, self).__init__(

            label=_('Repository'),

            db_field='repository__name',

            shrink=True,

            sortable=True,

            link=True,

            link_func=self.link_to_object,

            css_class='repository-column',

            *args, **kwargs)

    def augment_queryset(self, state, queryset):

        return queryset.select_related('repository')

    def render_data(self, state, obj):

        return super(RepositoryColumn, self).render_data(state, obj) or ''

    def link_to_object(self, state, obj, value):

        import urllib

        return local_site_reverse('all-review-requests',

                                  request=state.datagrid.request) + '?' +

               urllib.urlencode({'repository':obj.repository_id})

在这里更改该列支持Link,接着定义
link_to_object函数,这里找了一段时间,发现local_site_reverse可以用于获取需要的url,然后再与url组合,一开始
没有使用urlencode,一直无法正常呈现。由于原来在ASP.NET中,使用过urlencode,知道这里面有坑,就网上查询了Python的
urlencode,然后解决之,发现可以工作了。不过,下一个问题来了,即链接后,如何进行过滤?这里发现其“show
closed”过滤功能,通过代码查询,知道在grids.py中,如何工作,那么,添加过滤也就不难了。如下。

grids.py 第116行

self.repository_query = ‘'

grids.py 第133行

      self.repository_query = self.request.GET.get('repository', '')       

      if len(self.repository_query) > 0:

           self.queryset = self.queryset.filter(repository_id=int(self.repository_query))

4 ReviewBoard令人震惊的优秀代码基因

顺利修改之后,我大为震惊,为ReviewBoard这款优秀的软件说叹服。为什么能够
在1天时间里面,从Python学习到对一个完全黑盒子的软件进行修改?答案就是ReviewBoard具有非常整洁的代码。也就是
说,ReviewBoard拥有非常优秀的内外部质量。

数据库设计,简单清晰,结构非常清晰,可读性很强,根本不需要任何数据库文档。文档是多余的!!!

代码风格非常一致,我们发现ReviewBoard的注释非常少,Bob大叔的《代码整
洁之道》强调了注释是代码意图表现失败的补充,最好的代码是一行注释都不要。ReviewBoard的命名,从前到后都非常一致,大小写、下划线、类名、

方法名规则统一,命名准确无误,没有不专业的命名,没有不专业的缩写。ReviewBoard的类都非常简单,在columns.py这个文件,你可以发

现每一个Column基本都在50行以内,每一个方法也非常简单。ReviewBoard非常完美的践行了单一职责,清晰的告诉我,要完成什么任务可以通

过哪些类、哪些方法、写什么样代码来完成。ReviewBoard代码风格非常优秀,没有丑陋的缩紧,没有丑陋的拥挤,在该有空格的时候空格,在该有空行
的时候空行,在该缩紧的时候缩紧。这里,我看不出任何代码腐败的味道。跟着这种优秀的软件“混”,我也很难写出差的代码。

在写代码这件小事上,可能很多人眼里只有架构、框架这类东西,可是实际上,很多工作多年
的程序员,代码依然是狗屎一样,没有规范的风格,没有良好的编码习惯。很多人能够去完成一件工作,但是,不漂亮。在没有意识的情况下,随着时间推移,只是

做的丑事更多而已。从我的编码经验,可以总结出一个程序员现状,1~3年的开发人员,处于混乱状态,他们能完成功能就不错了;3~5年的开发人员,有些抽

象意识,但是,一种是走向黑客,代码抽象的只有自己和上帝看得懂,一种是变得专业,倾向编写一些让团队其他人员看得懂的代码,还有一种就是保持现状;5年

之后,开发人员又是三类,一类走向管理,也是不错选择,一类走向更高的技术路线如架构师或者专家,还有一类,就是变成废物,随着时间的推移,他们越来越没

有空间,越来越没有价值。一般而言,通过培养,年纪越轻的人,成长越快,越有前途,要提升他们的水平,代码评审是最有效的方法,通过评审和培训让他们知道
什么是美、什么是丑,什么是优秀、什么是低劣。

5 致敬

再次致敬ReviewBoard!ReviewBoard既是提升我们整体实力的有效工具,也是一款值得学习的软件,感谢ReviewBoard!(我激动的想给它捐款时,竟然找不到按钮~~)

另外,我们使用了TaoReviewBoard、FindBugs、JSHint这些工具,感谢你们~~。

在代码评审,我大量引用Bob大叔的两本著名书籍《代码整洁之道》、《程序员的职业素养》,非常好的书,感谢Bob大叔!

作者:道法自然

来源:51CTO

时间: 2024-10-30 22:17:55

分享让人折服的优秀代码基因的相关文章

阅读优秀代码是提高开发人员修为的一种捷径

导读:原文作者Alan Skorkin是一名软件开发人员,他在博客<Why I Love Reading Other People's Code And You Should Too>中分享对软件开发相关的心得.Alan认为:阅读优秀代码是提高开发人员修为的一种捷径.以下是全文: 我突然想起来,很多程序员都讨厌阅读代码.来吧,承认吧! 每个人都喜欢编写代码,编代码是件趣事. 另一方面,阅读代码也不容易. 不仅不容易(编注:参见<微软资深软件工程师:阅读代码不容易>),而且还非常枯燥

网页教学网代码分享:干净简洁的网页列表代码

文章简介:网页教学网代码分享:干净简洁的网页列表代码.  谁不希望有一个好看而又干净的网页列表?这篇文章中我们给出几个实用的例子,你可以把他们直接用到自己的工作中. 我们从一个带有动画效果的垂直列表开始,接着是一个图文混排的例子,然后是一个只有图片的list例子跟一个水平菜单的例子,最后是一个以放大数字开头的列表.对于初学者而言这里可以学到很多东西,对于熟手,直接拿来用就是了. 1.helvetica字体的列表 第一个例子的样式看起平淡无奇,不过喜欢简约风格的人也许会感兴趣,这类似于印刷字体风格

你见过中文编程的代码吗?台湾人这段中文代码真是逆天了!

最近几天,各大网站都在发布热门编程语言排行版.点进去一看,最热门的语言是JAVA,位列第二第三的分别是C语言和C++,第四第五是C#和python.为什么热门的编程语言都是英语,而没有中文编程语言.也许很多人会说这个问题没有营养,但是关于这个问题的谈论,却始终没有消停. 热门语言排行版 W3Cschool小师妹在某个贴吧上看到一个很有意思的话题,那就是"我们离汉语编程有多远". 贴吧截图 吧主称文字很有魅力,可以穿越空间.时间,带给大家新的认识.21世纪,如果你不会编程,那么你就是文盲

wifi-关于写个判断接入宽带的适配器并且分享给虚拟网卡的C++代码

问题描述 关于写个判断接入宽带的适配器并且分享给虚拟网卡的C++代码 我想模仿一键WIFI自己写个MFC的程序,提升提升自己.一个地方是不想弹cmd窗口,还有我想一键设置适配器分享网络,不想手动设置.我自己网上查了下,好像这些是和API有关的,百度了很多,实在是知识匮乏,搞不太懂,求教. 解决方案 如果你什么都不会,还是去威客网雇佣一个初级程序员帮你吧,也就几百块钱. 解决方案二: 找了这么多,找到MSDN里面的.啃英语吧.https://msdn.microsoft.com/en-us/lib

分享两段简单的JS代码防止SQL注入_javascript技巧

1.URL地址防注入: //过滤URL非法SQL字符 var sUrl=location.search.toLowerCase(); var sQuery=sUrl.substring(sUrl.indexOf("=")+1); re=/select|update|delete|truncate|join|union|exec|insert|drop|count|'|"|;|>|<|%/i; if(re.test(sQuery)) { alert("请勿

分享12个实用的jQuery代码片段_jquery

jQuery是一款优秀的JavaScript库,它在WEB开发者和网页设计师中非常出名,帮助网页设计师开发出很多有创意和漂亮的WEB页面. 本文主要分享了12个有用的jQuery技巧,具体内容如下 下面是我收集的一些小技巧,这些技巧将帮助你提高你网站布局和应用的创意性以及功能性. 一.在新窗口打开链接 用这个代码,你点击超文本链接时会在新窗口中打开,为用户带来更好的体验: $(document).ready(function() { //select all anchor tags that h

让人生厌的社交分享让人疲于分享

现在的互联网产品已经严重被各色社交分享按扭所荼毒了!几乎大部分应用与游戏不管是电脑端还是手机端,少不了都会跟风加上社交分享按钮.一天始倒不觉得什么,但当这样的按钮满天飞的时候我觉得只要我一打开网页打开手机全特么是分享按钮!!这难道不会是种使用上的疲劳么. 且不说这样的按钮究竟为应用本身带来了多大的宣传效果,就我个人而言,我是吃错了药才会没事帮别人打广告,比如分享一个店铺到我的扣扣空间或者Google+去!相反当我打开扣扣空间想关注一下朋友们的动态的时候,我期望看到的是大家的心情,从中我可以了解到

任正非:坚持创新走出迷航 用最优秀的人培养更优秀的人

全国科技创新大会于2016年5月30日在人民大会堂盛大开幕,习近平总书记发表重要讲话.李克强总理主持会议,两院院士齐聚一堂,共商国内科技发展.在如此高规格的大会上,华为创始人.总裁任正非出席会议并代表华为做了<以创新为核心竞争力 为祖国百年科技振兴而奋斗>的汇报发言,干货满满. 作为国内科技界的企业代表和中国在世界上的一张名片,华为在ICT行业的地位无以撼动.但面对未来,仍有诸多不确定性和挑战性.他表示,从科技的角度来看,未来二.三十年人类社会将演变成一个智能社会,其深度和广度我们还想象不到.

淘宝直播技术分享:如何打造体验优秀的“直播+”产品?

2016年是移动直播爆发年,不到半年的时间内无数移动直播App掀起了全民直播的热潮.很多不同产品都在自己的应用里面增加了直播模块,希望能趁着这波移动直播的风潮能快速推进自己的产品.而在电商类的APP中,淘宝率先在手机直播里面试水电商直播,并用实际的数据证明了这是一种非常具备前景的新模式. 本文将重点介绍淘宝直播在业务模式上的探索.移动直播背后的技术难点.优化用户体验等方面的内容.主要内容出自阿里巴巴高级技术专家陈举锋(丰火)在2016杭州云栖大会上的分享. 淘宝直播的产品探索 淘宝直播项目,于2