1、首先態(tài)度需要端正,做代碼的自我審查并不是否定自己,而是給自己將工作做得更好的一次機(jī)會。在審查過程中要盡量將自己作為一個旁觀者的心態(tài)去審查自己的代碼,盡管這比較困難。
2、代碼審查離不開重構(gòu),在審查過程中發(fā)現(xiàn)任何壞味道都請使用重構(gòu)去改善,發(fā)現(xiàn)缺乏測試的地方要及時補(bǔ)充測試,不要讓BUG遺漏。
3、代碼的自我審查可能不是越早越好,隔一段時間之后回去看自己寫的東西,對一些設(shè)計(jì)上的選擇能有更客觀的評價,在審查的過程中可能需要重新去理解代碼,在此過程中可以檢查自己代碼的可讀性,并思考如何改善可讀性,切記代碼首先是給人讀的。
4、審查過程中需要記錄下一些犯下的錯誤,以及當(dāng)時為什么會犯下這樣的錯誤,建立自己的bug數(shù)據(jù)庫,并時常review,在以后的工作中避免同樣的錯誤。
5、代碼的自我審查應(yīng)該是一個持續(xù)性的過程,而非特定時間的特定行動,時常審查自己的代碼,不僅能辨析自己的得失,還能夠進(jìn)一步提高自己在未來工作中的設(shè)計(jì)能力和預(yù)見能力。
6、代碼的自我審查跟團(tuán)隊(duì)成員之間的相互review并不矛盾,在相互review之前做一個自我審查,有助于提高review的效率,包括可讀性的提高和一些一般錯誤的避免。
7、代碼自我審查的一些常見注意點(diǎn):
(0)自認(rèn)為絕不會出錯,并且從來沒有審查過的代碼。
(1)注意else語句,if條件下的子語句通常可能是個正常的流程,而else意味著異常的情況或者特殊的場景,你可能特別注意怎么處理正常的情況,卻忽略了else子句的實(shí)現(xiàn)細(xì)節(jié),如該釋放的鎖沒釋放,該遞減的計(jì)數(shù)沒有遞減,該賦予特殊值卻沒有賦予等等。
(2)注意空的方法,沒有方法體的方法,是不需要實(shí)現(xiàn)?還是忘了實(shí)現(xiàn)?
(3)注意switch語句,有沒有忘了break?這種錯誤通過findbugs之類的靜態(tài)代碼檢查工具都能避免。
(4)注意大塊的注釋,為什么這么多注釋?是代碼寫的很糟糕?還是遺留的注釋?遺留的注釋會誤導(dǎo)人,要及時刪除。
(5)注意一些看起來“不合常理”的代碼,這樣的代碼很多都是基于所謂性能考慮而優(yōu)化過的代碼,這樣的優(yōu)化是否還需要?是否能去除這些“奇怪”的代碼也能實(shí)現(xiàn)正常的需求?
(6)對客戶端的使用有假設(shè)的代碼,假設(shè)用戶只會這么用,假設(shè)用戶只會用到返回對象中的某些屬性,其他屬性一定不會用到?不要對客戶代碼做假設(shè)!這個客戶代碼包括外部用戶和調(diào)用這個模塊的內(nèi)部代碼。
(7)標(biāo)注了FIXME、TODO之類task標(biāo)簽的代碼,是否忘了修復(fù)BUG,實(shí)現(xiàn)功能?
(8)任何超過15行以上的方法,這些方法是否能拆分成更細(xì)粒度的方法,并保持在同一個抽象層次上?
(9)任何在代碼中出現(xiàn)的常量值,是否應(yīng)該提取出來成為單獨(dú)的常量,常量的默認(rèn)值設(shè)置是否合理?
(10) 任何持有容器的代碼,提供了放入容器的方法,是否提供了從容器中移除對象的方法?確保沒有內(nèi)存泄漏的隱患。
(11)重構(gòu)中提到的其他壞味道,別放過它們,但是也不要追求完美,OO不是圣杯,如果能簡單的實(shí)現(xiàn)一個算法,你不要引入3個對象和4個接口。
(12)在review最后能列出一張清單,開列下該項(xiàng)目面臨的風(fēng)險點(diǎn),并提出解決辦法,然后按照這張清單去review關(guān)鍵代碼,著重檢查異常情況下的處理。風(fēng)險點(diǎn)的review,我建議可以放在后面,在一般性錯誤解決之后進(jìn)行,此時你對代碼也將再度變的熟悉。