敏捷开发中的Code Review
敏捷開(kāi)發(fā)中的Code Review
?
一些敏捷團(tuán)隊(duì)在實(shí)施敏捷開(kāi)發(fā)中忙于編碼、忙于Unit?Test、忙于溝通、忙于Build等,雖然也有編碼審核階段,但大都浮于表面,流于形式,效果不佳。本文結(jié)合實(shí)踐,介紹筆者對(duì)敏捷開(kāi)發(fā)中CodeReview的理解和相關(guān)經(jīng)驗(yàn)
?
文/陳序明 黃彥軍
?
敏捷開(kāi) 發(fā)中Code?Review的目的及內(nèi)容
做任何事情,首先要清晰為什么要做,才能有目標(biāo)和動(dòng)力把事情做得更好,Code?Review?也是如此。只有清晰明確了敏捷團(tuán)隊(duì)進(jìn)行CodeReview?的動(dòng)機(jī),才能以此為方向開(kāi)展后續(xù)工作。下面我們推薦的敏捷開(kāi)發(fā)中常見(jiàn)的Code?Review的目的:
?
設(shè)計(jì)合理性Review
在筆者的另一篇文章中《敏捷開(kāi)發(fā)中的架構(gòu)設(shè)計(jì)》談到,敏捷開(kāi)發(fā)中崇尚Code?is?design,對(duì)開(kāi)發(fā)人員提出了比以往更高的要求,即需要開(kāi)發(fā)人員不斷地重構(gòu)出合理的設(shè)計(jì)。所以敏捷開(kāi)發(fā)中的Code?Review也需要承擔(dān)一部分“結(jié)對(duì)設(shè)計(jì)”和“設(shè)計(jì)把關(guān)”的職責(zé)。
這部分的Code?Review?包括:設(shè)計(jì)的合理性(如實(shí)現(xiàn)方法,數(shù)據(jù)結(jié)構(gòu),設(shè)計(jì)模式,擴(kuò)展性考慮等),是否存在大量重復(fù)代碼和其他組件是否有重復(fù)的代碼,包結(jié)構(gòu)設(shè)計(jì)是否合理等。
筆者了解的一些項(xiàng)目中,?進(jìn)行敏捷開(kāi)發(fā)后,?提高了開(kāi)發(fā)效率,?但是設(shè)計(jì)的質(zhì)量卻下降了。如Repeat Yourself?的現(xiàn)象(特別是跨組件之間的Repeat?Yourself?現(xiàn)象);更有甚者,在筆者看到一個(gè)某銀行的應(yīng)用中(不是國(guó)內(nèi)的),數(shù)據(jù)庫(kù)連接和操作是直接在JSP中寫SQL語(yǔ)句。
像這些Bad?Design?的例子還是很多的。這些在重構(gòu)的時(shí)候應(yīng)該由開(kāi)發(fā)人員解決。但考慮到不同開(kāi)發(fā)人員之間技術(shù)功底不一,很有必要在Code Review階段進(jìn)行Review和討論。
互為Backup
這是很容易被忽略,但是又很重要的一個(gè)Code?Review的目的。
我們知道,敏捷開(kāi)發(fā)中強(qiáng)調(diào)高質(zhì)量的代碼勝過(guò)詳細(xì)的文檔,所以某種程度上來(lái)說(shuō)Code?is?Document。敏捷開(kāi)發(fā)中的代碼承擔(dān)了一部分Document的職責(zé),即傳遞技術(shù)的作用。
Code?Review?中,Review?的開(kāi)發(fā)人員了解代碼的設(shè)計(jì)和實(shí)現(xiàn),傳遞了技術(shù),開(kāi)發(fā)人員互為Backup,方便后期的維護(hù),也減少了項(xiàng)目風(fēng)險(xiǎn)。
?
分享知識(shí)、設(shè)計(jì)、技術(shù)
這也是很容易被忽略的一個(gè)很重要的目的。敏捷開(kāi)發(fā)是一個(gè)中央集中控制到個(gè)體發(fā)揮積極性的過(guò)程,中央集中控制的優(yōu)點(diǎn)就是有統(tǒng)一的視圖和控制,經(jīng)常開(kāi)大會(huì),開(kāi)長(zhǎng)會(huì),這樣知識(shí)和經(jīng)驗(yàn)也較容易集中。敏捷開(kāi)發(fā)中,分散在兩個(gè)Scrum?Team的開(kāi)發(fā)人員之間,如果沒(méi)有好的機(jī)制,相互溝通也會(huì)相對(duì)較少,造成知識(shí)和好的經(jīng)驗(yàn)無(wú)法在整個(gè)團(tuán)隊(duì)傳播。
筆者參加的項(xiàng)目中就碰到了類似情況,?當(dāng)時(shí)我們整個(gè)團(tuán)隊(duì)分成三個(gè)Scrum?Team,其中一個(gè)Scrum?Team負(fù)責(zé)一個(gè)Eclipse?工具的開(kāi)發(fā),?其中用到的一些功能和知識(shí)在其他ScrumTeam上以前都有涉及過(guò)。當(dāng)時(shí)負(fù)責(zé)開(kāi)發(fā)的同事非常優(yōu)秀而且能力突出,但由于不知道其他Scrum?Team同事有這方面的經(jīng)驗(yàn),沒(méi)有很好地分享以往好的經(jīng)驗(yàn)和知識(shí),以至于最后導(dǎo)致浪費(fèi)了一些學(xué)習(xí)的成本。
Code?Review是一個(gè)學(xué)習(xí)和享受的過(guò)程,一個(gè)開(kāi)發(fā)人員的能力有限,而Code?Review正是這樣的一種機(jī)制,讓好的知識(shí)、設(shè)計(jì)在團(tuán)隊(duì)中分享,實(shí)現(xiàn)整體團(tuán)隊(duì)的成長(zhǎng)和整體的效益最大化。
?
代碼可讀性
如上所說(shuō),敏捷開(kāi)發(fā)中強(qiáng)調(diào)高質(zhì)量的代碼勝過(guò)冗余的文檔,所以Code某種程度上是Document。敏捷開(kāi)發(fā)中,代碼的要求不止是能運(yùn)行功能正確的代碼,而是有了更高的要求,即Code for?maintenance。
可維護(hù)的代碼,需要清晰,可讀性強(qiáng),這里可讀性代碼檢查不是指代碼格式(代碼格式可以通過(guò)工具檢查出),而是指代碼語(yǔ)義。在筆者的文章《軟件可消費(fèi)性設(shè)計(jì)》中有一些這方面的討論和建議。
?
Code中的“地雷區(qū)”Review
代碼中的邏輯,除了業(yè)務(wù)邏輯,還應(yīng)該包括技術(shù)邏輯。技術(shù)邏輯就是實(shí)現(xiàn)邏輯,?比如數(shù)據(jù)庫(kù)連接打開(kāi)是否忘記關(guān)閉,是否正確使用線程,Exception?處理,密碼是否加密存儲(chǔ)等。
我把這些最常出現(xiàn)錯(cuò)誤的地方,而且是測(cè)試不容易發(fā)現(xiàn)的地方,稱為Code中的“地雷區(qū)”。這些“地雷區(qū)”在Code?Review?中是值得花費(fèi)一些時(shí)間進(jìn)行維護(hù)和檢查的。
建議,在整個(gè)團(tuán)隊(duì)中維護(hù)并共享“地雷區(qū)”注意事項(xiàng)列表,以及統(tǒng)一的處理方式和機(jī)制。并在編碼和Code?Review過(guò)程中都按照?qǐng)F(tuán)隊(duì)的最佳實(shí)踐進(jìn)行。
?
發(fā)現(xiàn)代碼中的業(yè)務(wù)邏輯錯(cuò)誤
業(yè)務(wù)邏輯指的是代碼開(kāi)發(fā)的功能是否符合業(yè)務(wù)需求,如一個(gè)加法函數(shù),檢查其是否真的實(shí)現(xiàn)了加法的功能。
筆者了解的一些敏捷團(tuán)隊(duì)中,把發(fā)現(xiàn)代碼的業(yè)務(wù)邏輯錯(cuò)誤當(dāng)做目標(biāo)和內(nèi)容,但往往效果都不是很好,基本都是從形式上泛泛檢查一番。原因有兩個(gè):
1.業(yè)務(wù)邏輯的檢查是從需求到代碼的全方位檢查,需要花費(fèi)大量時(shí)間,投入產(chǎn)出比失衡。
2.業(yè)務(wù)邏輯的檢查和業(yè)務(wù)需求緊密關(guān)聯(lián),已經(jīng)超出了檢查人員的能力范圍(一般Code?Review是開(kāi)發(fā)人員,不是業(yè)務(wù)人員)。
筆者認(rèn)為,發(fā)現(xiàn)邏輯錯(cuò)誤,不應(yīng)該是Code?Review?的目的和內(nèi)容。應(yīng)該是Unit?Test,功能測(cè)試,集成測(cè)試的目的。從投入產(chǎn)出比考慮,不應(yīng)該花費(fèi)太多時(shí)間在Code?Review?階段去進(jìn)行邏輯錯(cuò)誤檢查。
?
敏捷開(kāi)發(fā)中不推薦的Code Review的目的及內(nèi)容
下面還有一些常見(jiàn)的Code?Review目的和內(nèi)容被很多團(tuán)隊(duì)廣泛使用,但作者認(rèn)為這些并不是敏捷開(kāi)發(fā)中的主要目的和內(nèi)容,團(tuán)隊(duì)?wèi)?yīng)該把時(shí)間花費(fèi)在重要的目的和內(nèi)容上,而不應(yīng)該投入精力在下面的這些Code?Review目的和內(nèi)容上。
?
發(fā)現(xiàn)性能問(wèn)題
有些團(tuán)隊(duì)把性能問(wèn)題,也作為Code Review的目的和內(nèi)容之一,然后提出一些如String應(yīng)該使用StringBuilder,而不能使用+,類似這樣的看似有用其實(shí)無(wú)用建議。
筆者認(rèn)為,性能問(wèn)題是需要量化的衡量和精確定位,?很難通過(guò)Code Review檢查出來(lái)。而一些粗淺的性能問(wèn)題可以通過(guò)一些工具方便地掃描出來(lái),而無(wú)須花費(fèi)時(shí)間去進(jìn)行Code?Review。
如圖1是RAD?V7.0?(IBM?Rati?onal Application?Developer)?中的Software Analyzer工具帶有的Performance檢查:
圖1 RAD Software Analyzer中的Performance檢查
所以筆者認(rèn)為,開(kāi)發(fā)人員提交的代碼,需要是經(jīng)過(guò)工具檢查后的代碼。而代碼審核人員則無(wú)須花費(fèi)時(shí)間在性能相關(guān)的Code?Review?上。具體的性能問(wèn)題交給性能測(cè)試。
?
發(fā)現(xiàn)開(kāi)源的授權(quán)法律問(wèn)題
開(kāi)源軟件也可以借助一些檢查工具,?統(tǒng)一通過(guò)工具掃描,?無(wú)需在Code?Review?階段花費(fèi)時(shí)間。
?
其他問(wèn)題,如國(guó)際化,J2EE?Best Practice等
這些問(wèn)題開(kāi)發(fā)人員可以在提交代碼之前通過(guò)工具發(fā)現(xiàn)和解決,?不是Code?Review?階段的職責(zé)和目的,也無(wú)須花費(fèi)時(shí)間去處理。
像FindBugs?和RAD?這樣的工具就具備類似的代碼檢查功能,如RADV7.0?中的Software?Analyzer?工具帶有如下的檢查功能:
圖2 RAD Software Analyzer中檢查規(guī)則列表
1.設(shè)計(jì)原則(5):用于面向?qū)ο缶幊痰脑O(shè)計(jì)原則的規(guī)則。
2.全球化(47):基于全球化編碼最佳實(shí)踐的規(guī)則,有助于確保代碼在局部環(huán)境中正確地運(yùn)行。
3.J2EE?最佳實(shí)踐(32):基于最佳的?Java??2?Platform?Enterprise Edition(?J2EE)開(kāi)發(fā)實(shí)踐的規(guī)則,以及支持瞄準(zhǔn)?IBM??WebSphere??服務(wù)的Web?項(xiàng)目的規(guī)則;
4.J2EE?安全性(17):驗(yàn)證代碼符合?J2EE?技術(shù)安全性需要的規(guī)則;
5.J2SE?最佳實(shí)踐(71):基于最佳的?Java?2?Platform?Standard?Edition (J2SE)開(kāi)發(fā)實(shí)踐的規(guī)則;
6.J2SE?安全性(9):驗(yàn)證代碼符合?J2SE?技術(shù)安全性需要的規(guī)則;
7.命名(2):關(guān)于?Java?代碼中命名約定的規(guī)則;
8.性能(26):加強(qiáng)在?Java?應(yīng)用程序中提高性能和減少存儲(chǔ)器足跡的建議的規(guī)則;
9.私有?API?(3):定位那些不屬于?Java?代碼的?API?的規(guī)則。
?
敏捷開(kāi)發(fā)中如何開(kāi)展Code Review
在清晰明確了敏捷團(tuán)隊(duì)進(jìn)行Code Review?的目的和內(nèi)容后,下面介紹如何有效地開(kāi)展Code?Review。
?
溝通、協(xié)作、互助、學(xué)習(xí)的團(tuán)隊(duì)氛圍
Code?Review?中,Review?人員和開(kāi)發(fā)人員不是對(duì)立的關(guān)系,而是互助、溝通、協(xié)作和學(xué)習(xí)的過(guò)程。團(tuán)隊(duì)形成互助、互學(xué)的氣氛,既能互相增長(zhǎng)團(tuán)隊(duì)的知識(shí)和經(jīng)驗(yàn),還能把產(chǎn)品做得更好。
Code?Review協(xié)作過(guò)程:
a)先由代碼的開(kāi)發(fā)人員向檢查人員進(jìn)行大體的介紹,包括設(shè)計(jì)思想、數(shù)據(jù)結(jié)構(gòu)、程序代碼結(jié)構(gòu)介紹等。
b)雙方進(jìn)行討論、交流。
c)檢查人員單獨(dú)進(jìn)一步進(jìn)行Code Review,并記錄Review結(jié)果和建議。
d)由檢查人員和開(kāi)發(fā)人員一起,檢查人員反饋Code?Review結(jié)果,并和開(kāi)發(fā)人員一起討論改進(jìn)方法,重構(gòu)。
e)最后把可重用的Code?Review的經(jīng)驗(yàn)總結(jié)編碼規(guī)范,或者記錄到“地雷區(qū)”中。便于整個(gè)團(tuán)隊(duì)復(fù)用經(jīng)驗(yàn)。
圖3 Code Review是溝通、協(xié)作、互助和學(xué)習(xí)的過(guò)程
開(kāi)展以上過(guò)程可以以開(kāi)發(fā)人員為主,輔助以工具。但無(wú)須規(guī)定系列的文檔、流程、Check?List?等,這反而會(huì)影響開(kāi)發(fā)人員的積極性。
Code?Review是發(fā)現(xiàn)問(wèn)題的過(guò)程,同時(shí)也是學(xué)習(xí)和交流過(guò)程。需要是靈活、自由、主動(dòng)的態(tài)度,而不是行政上的控制和規(guī)章流程。筆者建議:和敏捷開(kāi)發(fā)的核心思想一致,讓團(tuán)隊(duì)明確Code?Review?的思想、作用和目的內(nèi)容后,充分發(fā)揮個(gè)體的積極性和學(xué)習(xí)分享的動(dòng)力。隨時(shí)隨地地進(jìn)行Code Review,討論,重構(gòu),改進(jìn)。
?
增量式Review
大家都知道,軟件開(kāi)發(fā)中存在長(zhǎng)鞭效應(yīng),即一個(gè)問(wèn)題越在后期發(fā)現(xiàn)造成的影響會(huì)越大,Code?Review?也是
如此,如圖4所示:
?
圖 4 Code Review中的長(zhǎng)鞭效應(yīng)
軟件的開(kāi)發(fā)過(guò)程中,?應(yīng)該階段性地進(jìn)行Code Review,而不是等到所有代碼都開(kāi)發(fā)完畢后再做一次性的Code?Review。那時(shí)如果發(fā)現(xiàn)問(wèn)題,造成的改動(dòng)成本比增量式的檢查來(lái)的大得多。
筆者了解的一些開(kāi)發(fā)團(tuán)隊(duì),他們?cè)谲浖_(kāi)發(fā)完畢,并測(cè)試后,才臨時(shí)確定Code?Review的人員,然后再安排半天左右的時(shí)間進(jìn)行Code?Review。結(jié)果盡管發(fā)現(xiàn)一些結(jié)構(gòu)或設(shè)計(jì)方面問(wèn)題,但由于修改成本大,也無(wú)法進(jìn)行改進(jìn)。
正確的方式是,在早期就參與設(shè)計(jì)開(kāi)發(fā)過(guò)程,抱著互助、溝通、協(xié)作、學(xué)習(xí)的思想,階段性的參與討論、學(xué)習(xí)并貢獻(xiàn)自己的意見(jiàn)。具體Review的頻率、次數(shù)則可以由開(kāi)發(fā)人員抱著主動(dòng)、積極的態(tài)度,按照敏捷的思想自己去把握決定。
?
利用工具進(jìn)行Code?Inspection
有很多的工具可以輔助Code Review?:
1.如代碼格式檢查Checkstyle?工具,檢查如過(guò)大的類、太長(zhǎng)的方法和未使用的變量等這樣違反編程規(guī)范的問(wèn)題。
2.RAD中的Software?Analyzer工具,可以基于規(guī)則進(jìn)行國(guó)際化、J2EE最佳實(shí)踐、性能、安全等檢查。3.CSAR,用于掃描代碼檢查開(kāi)源軟件等。
4.JDepend,可以檢查包依賴關(guān)系。
5.CPD工具,Eclipse?的?PMD?插件提供了一項(xiàng)叫做?CPD(或復(fù)制粘貼探測(cè)器)的功能,用于尋找重復(fù)的代碼。
6.Eclipse?的Metrics?插件,提供了很多有效地查出代碼復(fù)雜度的功能。
輔助以工具和自動(dòng)化流程,能花很少時(shí)間輕松完成很多基本的Code Inspection?工作。讓團(tuán)隊(duì)有更多的時(shí)間和精力去做更重要的Code?Review。
?
持續(xù)自動(dòng)化Code?Inspection
工具檢查可以由開(kāi)發(fā)人員自行檢查并修正,?但一種更可持續(xù)的做法是自動(dòng)化的集成工具進(jìn)行Code Inspection,可以通過(guò)自動(dòng)化腳本在每日進(jìn)行Build?前進(jìn)行掃描,并呈現(xiàn)報(bào)告給相應(yīng)人員。
?
Code?Review協(xié)作工具
為了快速有效地進(jìn)行人工Code Review協(xié)作,可以使用諸如Jupiter這樣的工具輔助進(jìn)行。可以幫助開(kāi)發(fā)人員有效管理Code?Review任務(wù)、問(wèn)題、建議等。
?
總結(jié)
Code?Review?的核心是:互助,溝通,協(xié)作,學(xué)習(xí)的過(guò)程,這是一個(gè)美妙而享受的過(guò)程,是跨越需求分析、架構(gòu)設(shè)計(jì)、編碼等各階段的過(guò)程。敏捷團(tuán)隊(duì)?wèi)?yīng)該統(tǒng)一達(dá)成Code?Review?對(duì)產(chǎn)品、對(duì)團(tuán)隊(duì)、對(duì)個(gè)人的巨大好處的共識(shí),發(fā)揮出個(gè)體的積極性,相信會(huì)改變“流于形式”的現(xiàn)狀,發(fā)揮Code Review巨大的威力。
?
作者簡(jiǎn)介:
陳序明,IBM公司顧問(wèn)軟件工程師。他目前在IBM中國(guó)北京研發(fā)中心工作,從事銀行多渠道整合(網(wǎng)上銀行、手機(jī)銀行、柜面等)方面的開(kāi)發(fā)和研究,對(duì)軟件架構(gòu)、敏捷開(kāi)發(fā)、產(chǎn)品管理和銀行業(yè)務(wù)很感興趣。
黃彥軍,IBM中國(guó)軟件研發(fā)中心軟件工程師,2008年在西安電子科技大學(xué)獲得計(jì)算機(jī)系統(tǒng)結(jié)構(gòu)碩士學(xué)位。目前主要從事中間件、Eclipse插件開(kāi)發(fā),深入理解C、C++、Java。感興趣的技術(shù)領(lǐng)域包括:分布式計(jì)算,網(wǎng)絡(luò)應(yīng)用等。
(本文來(lái)自《程序員》雜志0912期)
from:http://www.programmer.com.cn/1310/
轉(zhuǎn)載于:https://www.cnblogs.com/dkblog/archive/2011/07/18/2109779.html
總結(jié)
以上是生活随笔為你收集整理的敏捷开发中的Code Review的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
                            
                        - 上一篇: 很实用的jQuery事件 - toggl
 - 下一篇: jws 方式表格导出,excel文件导出