自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

分享讓人折服的優(yōu)秀代碼基因

開(kāi)發(fā) 后端 前端
近來(lái)參與一個(gè)較大團(tuán)隊(duì)的項(xiàng)目實(shí)施,項(xiàng)目的金額幾千萬(wàn),人數(shù)近百。但是,項(xiàng)目實(shí)施后,暴露出幾個(gè)問(wèn)題.

1 背景

近來(lái)參與一個(gè)較大團(tuán)隊(duì)的項(xiàng)目實(shí)施,項(xiàng)目的金額幾千萬(wàn),人數(shù)近百。但是,項(xiàng)目實(shí)施后,暴露出以下幾個(gè)問(wèn)題:

(1)質(zhì)量不佳,團(tuán)隊(duì)成員水平參差不齊,軟件外部質(zhì)量、內(nèi)部質(zhì)量一致性差;

(2)需求不確定,時(shí)間非常緊,代碼頻繁修改,越來(lái)越丑,效率變低。

為了保證項(xiàng)目按時(shí)按質(zhì)交付,質(zhì)量改善刻不容緩。因此,在項(xiàng)目的初中期開(kāi)始,做了以下三件事情:

(1)制定統(tǒng)一的界面規(guī)范,制定了統(tǒng)一參考實(shí)例,為所有成員進(jìn)行定期界面規(guī)范的培訓(xùn)和評(píng)審;

(2)制定統(tǒng)一的代碼規(guī)范,制定了《評(píng)審文化構(gòu)建》、《代碼之丑》PPT,培養(yǎng)團(tuán)隊(duì)的質(zhì)量文化和評(píng)審文化,實(shí)施評(píng)審;

(3)引入管理工具ReviewBoard。

項(xiàng)目統(tǒng)一構(gòu)建了標(biāo)準(zhǔn)、規(guī)范,有效保證了界面的一致性,但是代碼質(zhì)量的提高卻不是那么簡(jiǎn)單的事情。在這里,我暫不分享項(xiàng)目的情況,未來(lái)會(huì)通過(guò)更加詳細(xì)的文章來(lái)介紹標(biāo)準(zhǔn)、規(guī)范化軟件開(kāi)發(fā)方法對(duì)于項(xiàng)目的重要性。

2 ReviewBoard介紹

這里倒是引出了一款優(yōu)秀工具ReviewBoard。這款工具簡(jiǎn)單易用,功能強(qiáng)大。通過(guò) 它來(lái)實(shí)施代碼評(píng)審非常有效。代碼評(píng)審分為提交前評(píng)審(Pre-Review)和提交后評(píng)審(Post-Review)兩種方式。提交前評(píng)審,即開(kāi)發(fā)人員代 碼變更后,需要提交到ReviewBoard,經(jīng)過(guò)評(píng)審?fù)ㄟ^(guò)后,才能提交到SVN源碼服務(wù)器,如果沒(méi)有通過(guò)評(píng)審,則代碼提交會(huì)失敗,一行都無(wú)法提交;提交 后評(píng)審,即開(kāi)發(fā)人員先提交代碼,然后再提交變更到ReviewBoard,如果評(píng)審未通過(guò),則修改代碼,更新評(píng)審直到通過(guò)為止。這兩種方式,各有優(yōu)劣,我 們采用的是后一種,它不阻塞開(kāi)發(fā)人員提交代碼,無(wú)法100%控制所有質(zhì)量,但是可以達(dá)到80%以上。

ReviewBoard設(shè)計(jì)之初更多考慮的是支持Pre-Review方式,因此,存在 以下問(wèn)題:(1)提交通過(guò)后,Review無(wú)法自動(dòng)進(jìn)行狀態(tài)變更為關(guān)閉,會(huì)與所有通過(guò)評(píng)審的ReviewRequest混在一起;(2)無(wú)法看出未通過(guò)評(píng) 審的請(qǐng)求進(jìn)行再次更新,因?yàn)槿绻俅胃潞?,意味著要進(jìn)行第二次評(píng)審。在管理過(guò)程中,會(huì)查詢哪些請(qǐng)求沒(méi)有通過(guò)評(píng)審,定期給開(kāi)發(fā)人員發(fā)送通知。

因此,我決定對(duì)ReviewBoard進(jìn)行訂制來(lái)支持以上功能。不 過(guò),ReviewBoard是基于Python語(yǔ)言和基于Django框架開(kāi)發(fā),我從來(lái)沒(méi)有學(xué)習(xí)過(guò)Python,更沒(méi)有學(xué)習(xí)過(guò)Django,那如何來(lái)修 改?所以,我開(kāi)始對(duì)ReviewBoard做研究。ReviewBoard***版本只能在非Windows運(yùn)行,我在Ubuntu 14.04安裝部署,同時(shí)使用MySQL數(shù)據(jù)庫(kù)。因此,我開(kāi)始來(lái)嘗試做修改。

3 嘗試修改ReviewBoard

3.1 探索***步:數(shù)據(jù)庫(kù)

首先,研究數(shù)據(jù)庫(kù),驚訝發(fā)現(xiàn)其數(shù)據(jù)庫(kù)設(shè)計(jì)非常的整齊,壓根不需要查看任何文檔即可知道數(shù) 據(jù)庫(kù)的表、字段的意義。我找到了幾個(gè)關(guān)鍵的表,分別是reviews_reviewrequest,看看其字段,與界面顯示幾乎一致,一下子就明白什么意 思,順著字段意思,找到了另外的兩個(gè)關(guān)鍵表diffviewer_diffsethistory、diffviewer_diffset。查詢一下這些表 的數(shù)據(jù),我很容易來(lái)解決***個(gè)問(wèn)題,通過(guò)一條SQL語(yǔ)句即可將通過(guò)評(píng)審的ReviewRequest關(guān)閉,這樣就不需要查看到這些評(píng)審請(qǐng)求了。

 

3.2 學(xué)習(xí)Python并修改代碼

接下來(lái)的第二個(gè)問(wèn)題,需要修改代碼,我花了3個(gè)小時(shí)學(xué)習(xí)了Python,通過(guò)在線的英文幫助,直接在控制臺(tái)做實(shí)驗(yàn),學(xué)習(xí)基本語(yǔ)法結(jié)構(gòu)、學(xué)習(xí)類(lèi)與對(duì)象編程、學(xué)習(xí)了Python模塊與編譯,對(duì)Python初步熟悉之后,我決定開(kāi)始來(lái)進(jìn)行代碼修改。

因此,我先通過(guò)相似列“Submitter”對(duì)所有文件進(jìn)行查詢,通過(guò)它很快找到了 columns.py和grids.py這兩個(gè)文件,看了代碼之后,發(fā)現(xiàn)ReviewBoard的評(píng)審請(qǐng)求通過(guò)這兩個(gè)文件來(lái)實(shí)現(xiàn),進(jìn)行再次查詢名稱(chēng)沒(méi)有再 發(fā)現(xiàn)關(guān)聯(lián)文件了。通過(guò)這兩個(gè)文件,可以發(fā)現(xiàn),columns.py用于定義要顯示的所有的列,grids.py進(jìn)行列的組合和顯示。那么接下來(lái)可以簡(jiǎn)單的 進(jìn)行模仿添加一個(gè)列了。該列定義為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

            """

        })

  

簡(jiǎn)單說(shuō)明一下,我定 義了DiffSetCountColumn類(lèi),繼承于Column類(lèi),類(lèi)初始化方法為_(kāi)_init__,相當(dāng)于構(gòu)造器。這里的self是以前經(jīng)常使用的 this,定義了兩個(gè)方法,一個(gè)是augment_queryset,用于當(dāng)前列的數(shù)據(jù)顯示,定義名稱(chēng)為mydiffsetcount,另外定義一個(gè)方法 render_data,即在表格中展現(xiàn)數(shù)據(jù)。這里參考了其它列定義。

接下來(lái)在grids.py中聲明對(duì)該列的使用,非常簡(jiǎn)單。

25行新增:

DiffSetCountColumn,

99行新增:

diffset_count = DiffSetCountColumn()

接著重啟Apache服務(wù)器,可以簡(jiǎn)單測(cè)試,驚訝發(fā)現(xiàn)可以工作了。

 

3.3 再進(jìn)一步添加功能

有了這次嘗試,我接下來(lái)想再進(jìn)一步來(lái)定制。目前各個(gè)小組提交到不同的SVN地址,通過(guò)SVN可以區(qū)分各個(gè)組提交情況。但是ReviewBoard沒(méi)有針對(duì)SVN地址的過(guò)濾。

首先修改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函數(shù),這里找了一段時(shí)間,發(fā)現(xiàn)local_site_reverse可以用于獲取需要的url,然后再與url組合,一開(kāi)始 沒(méi)有使用urlencode,一直無(wú)法正常呈現(xiàn)。由于原來(lái)在ASP.NET中,使用過(guò)urlencode,知道這里面有坑,就網(wǎng)上查詢了Python的 urlencode,然后解決之,發(fā)現(xiàn)可以工作了。不過(guò),下一個(gè)問(wèn)題來(lái)了,即鏈接后,如何進(jìn)行過(guò)濾?這里發(fā)現(xiàn)其“show closed”過(guò)濾功能,通過(guò)代碼查詢,知道在grids.py中,如何工作,那么,添加過(guò)濾也就不難了。如下。

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令人震驚的優(yōu)秀代碼基因

順利修改之后,我大為震驚,為ReviewBoard這款優(yōu)秀的軟件說(shuō)嘆服。為什么能夠 在1天時(shí)間里面,從Python學(xué)習(xí)到對(duì)一個(gè)完全黑盒子的軟件進(jìn)行修改?答案就是ReviewBoard具有非常整潔的代碼。也就是 說(shuō),ReviewBoard擁有非常優(yōu)秀的內(nèi)外部質(zhì)量。

數(shù)據(jù)庫(kù)設(shè)計(jì),簡(jiǎn)單清晰,結(jié)構(gòu)非常清晰,可讀性很強(qiáng),根本不需要任何數(shù)據(jù)庫(kù)文檔。文檔是多余的?。。?/p>

代碼風(fēng)格非常一致,我們發(fā)現(xiàn)ReviewBoard的注釋非常少,Bob大叔的《代碼整 潔之道》強(qiáng)調(diào)了注釋是代碼意圖表現(xiàn)失敗的補(bǔ)充,***的代碼是一行注釋都不要。ReviewBoard的命名,從前到后都非常一致,大小寫(xiě)、下劃線、類(lèi)名、 方法名規(guī)則統(tǒng)一,命名準(zhǔn)確無(wú)誤,沒(méi)有不專(zhuān)業(yè)的命名,沒(méi)有不專(zhuān)業(yè)的縮寫(xiě)。ReviewBoard的類(lèi)都非常簡(jiǎn)單,在columns.py這個(gè)文件,你可以發(fā) 現(xiàn)每一個(gè)Column基本都在50行以內(nèi),每一個(gè)方法也非常簡(jiǎn)單。ReviewBoard非常***的踐行了單一職責(zé),清晰的告訴我,要完成什么任務(wù)可以通 過(guò)哪些類(lèi)、哪些方法、寫(xiě)什么樣代碼來(lái)完成。ReviewBoard代碼風(fēng)格非常優(yōu)秀,沒(méi)有丑陋的縮緊,沒(méi)有丑陋的擁擠,在該有空格的時(shí)候空格,在該有空行 的時(shí)候空行,在該縮緊的時(shí)候縮緊。這里,我看不出任何代碼腐敗的味道。跟著這種優(yōu)秀的軟件“混”,我也很難寫(xiě)出差的代碼。

在寫(xiě)代碼這件小事上,可能很多人眼里只有架構(gòu)、框架這類(lèi)東西,可是實(shí)際上,很多工作多年 的程序員,代碼依然是狗屎一樣,沒(méi)有規(guī)范的風(fēng)格,沒(méi)有良好的編碼習(xí)慣。很多人能夠去完成一件工作,但是,不漂亮。在沒(méi)有意識(shí)的情況下,隨著時(shí)間推移,只是 做的丑事更多而已。從我的編碼經(jīng)驗(yàn),可以總結(jié)出一個(gè)程序員現(xiàn)狀,1~3年的開(kāi)發(fā)人員,處于混亂狀態(tài),他們能完成功能就不錯(cuò)了;3~5年的開(kāi)發(fā)人員,有些抽 象意識(shí),但是,一種是走向黑客,代碼抽象的只有自己和上帝看得懂,一種是變得專(zhuān)業(yè),傾向編寫(xiě)一些讓團(tuán)隊(duì)其他人員看得懂的代碼,還有一種就是保持現(xiàn)狀;5年 之后,開(kāi)發(fā)人員又是三類(lèi),一類(lèi)走向管理,也是不錯(cuò)選擇,一類(lèi)走向更高的技術(shù)路線如架構(gòu)師或者專(zhuān)家,還有一類(lèi),就是變成廢物,隨著時(shí)間的推移,他們?cè)絹?lái)越?jīng)] 有空間,越來(lái)越?jīng)]有價(jià)值。一般而言,通過(guò)培養(yǎng),年紀(jì)越輕的人,成長(zhǎng)越快,越有前途,要提升他們的水平,代碼評(píng)審是最有效的方法,通過(guò)評(píng)審和培訓(xùn)讓他們知道 什么是美、什么是丑,什么是優(yōu)秀、什么是低劣。

5 致敬

再次致敬ReviewBoard!ReviewBoard既是提升我們整體實(shí)力的有效工具,也是一款值得學(xué)習(xí)的軟件,感謝ReviewBoard?。ㄎ壹?dòng)的想給它捐款時(shí),竟然找不到按鈕~~)

另外,我們使用了TaoReviewBoard、FindBugs、JSHint這些工具,感謝你們~~。

在代碼評(píng)審,我大量引用Bob大叔的兩本著名書(shū)籍《代碼整潔之道》、《程序員的職業(yè)素養(yǎng)》,非常好的書(shū),感謝Bob大叔!

責(zé)任編輯:王雪燕 來(lái)源: 51CTO
相關(guān)推薦

2022-03-04 06:46:30

Python代碼

2012-09-04 09:55:22

代碼抓狂的代碼開(kāi)發(fā)

2019-06-13 16:30:37

代碼Java編程語(yǔ)言

2022-12-15 19:27:33

多線程代碼性能

2017-03-13 09:07:05

測(cè)定代碼基因

2023-03-15 15:54:36

Java代碼

2009-08-14 09:19:15

Windows 7XP模式優(yōu)缺點(diǎn)

2017-05-08 17:39:30

oppo

2022-03-08 14:02:35

GuavaMapjava

2010-06-03 11:03:20

2015-09-21 14:44:54

物聯(lián)網(wǎng)

2011-09-15 09:19:30

2020-03-09 14:10:48

代碼開(kāi)發(fā)工具

2022-10-09 18:39:46

分層代碼復(fù)用

2020-11-27 11:19:55

開(kāi)發(fā)API工具

2021-11-30 08:12:04

物流訂單實(shí)踐

2011-07-05 11:08:05

程序員

2020-05-25 11:14:59

代碼程序開(kāi)發(fā)

2017-11-09 12:33:02

程序員代碼技巧

2013-11-26 16:00:38

鷹眼監(jiān)控軟件QHM闊利達(dá)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)