文檔代碼同源,顧名思義,就是文檔和代碼都寫在源代碼文件里。這樣可以:1.修改代碼的時(shí)候就及時(shí)修改文檔,使得文檔和代碼及時(shí)保持一致;2.閱讀代碼時(shí),增加代碼的可讀性。評(píng)審代碼的時(shí)候,尤其是修改時(shí)后,即對(duì)文檔一同評(píng)審。結(jié)合研發(fā)流程、評(píng)審的配合,可促使代碼、文檔的開發(fā)逐步走向一一對(duì)應(yīng),逐步向高質(zhì)量發(fā)展,同時(shí)也能提高團(tuán)隊(duì)素質(zhì)。 一、問(wèn)題起源 互聯(lián)網(wǎng)行業(yè)和一些物聯(lián)網(wǎng)行業(yè),軟件開發(fā)都提倡敏捷開發(fā),敏捷開發(fā)為何物?(附件介紹。)這里列出敏捷的宣言: 個(gè)體和互動(dòng) 高于 流程和工具 工作的軟件 高于 詳盡的文檔 客戶合作 高于 合同談判 響應(yīng)變化 高于 遵循計(jì)劃 也就是說(shuō),盡管右項(xiàng)有其價(jià)值, 我們更重視左項(xiàng)的價(jià)值 很多公司所謂的敏捷,很大程度上就是開發(fā)代碼,應(yīng)該有的必要文檔可能都是不全的。因?yàn)橐s工,因?yàn)槭袌?chǎng)的巨大壓力,文檔代碼對(duì)應(yīng)不上司空見慣。更有甚者,壓根就沒(méi)有文檔。這里造成了很多隱性的問(wèn)題。 1.沒(méi)有合適的文檔,隨著時(shí)間的推移,一些技術(shù)要點(diǎn),設(shè)計(jì)要求,設(shè)計(jì)思路隨著時(shí)間,盡歸塵土。這些通過(guò)市場(chǎng)、技術(shù)、商業(yè)等各個(gè)維度試錯(cuò)的來(lái)的寶貴經(jīng)驗(yàn)和知識(shí)無(wú)法傳承,是一種浪費(fèi),更是一種低效組織的表現(xiàn)。 2.關(guān)鍵崗位的開發(fā)人員一旦流失,產(chǎn)生的技術(shù)、知識(shí)斷崖,短期內(nèi)難以補(bǔ)足。 3.新人的進(jìn)入,需要長(zhǎng)時(shí)間的消化理解。 4.代碼的評(píng)審和檢查不嚴(yán)格,想怎樣改就怎樣改,只要外在的功能是正常的。那就是沒(méi)有問(wèn)題的。為很多問(wèn)題埋下了伏筆和隱患。 敏捷中有一個(gè)觀點(diǎn),竊以為是無(wú)比正確的:沒(méi)有什么文檔比代碼更準(zhǔn)確。但這個(gè)觀點(diǎn)又是比較危險(xiǎn)的: 1.可運(yùn)行的功能正確的代碼的確是沒(méi)有什么比其更準(zhǔn)確的了。但是,代碼畢竟是寫給機(jī)器運(yùn)行的,個(gè)人的能力、習(xí)慣等都不一致,其他人理解起來(lái)必然費(fèi)勁。有一些飽含技巧的寫法可能是需求的需要,也可能是個(gè)人炫技的需要;其他人又怎能看透全部呢?代碼畢竟是非自然語(yǔ)言,有時(shí)候能看得懂代碼,是以犧牲速度為代價(jià)的,總之,問(wèn)題比較多。 2.潛臺(tái)詞是,文檔不重要。 總之,文檔、代碼的問(wèn)題,不僅困擾著程序員,也困擾著公司。那么怎么找一個(gè)合適的方法解決這個(gè)問(wèn)題呢? 二、解決方案 想想程序員為什么寫或修改代碼?我想即使是為了拯救地球和全宇宙,從微觀上講,也符合下列情況之一: 1.實(shí)現(xiàn)需求。是的,這怕是程序員寫/修改代碼的第一大原因了。 2.抓Bug。程序員實(shí)現(xiàn)需求的副產(chǎn)品:八阿哥(bug)。把它送走,是我們改代碼的第二大驅(qū)動(dòng)。 3.其他原因,諸如設(shè)計(jì)不足,可理解性不好啦,模塊用起來(lái)不爽啦,封裝不夠簡(jiǎn)潔實(shí)用,有一些程序員還有潔癖。這可能都是修改代碼的原因。但從本質(zhì)上來(lái)講,也是滿足需求的修改。每個(gè)產(chǎn)品需求定義之外,都有灰色邊界。需求提得越清楚,灰色地帶就越少。閱讀性不好、模塊用起來(lái)不爽,可能在需求里沒(méi)有提出來(lái)。有些作為需求提出來(lái),也是可以的。比如說(shuō),對(duì)于產(chǎn)品某個(gè)模塊的要求,必須使用什么標(biāo)準(zhǔn)技術(shù)或模塊,或者必須滿足下一代的復(fù)用等。至于潔癖,團(tuán)隊(duì)沒(méi)有定義團(tuán)隊(duì)的寫法,那么沖突修改是必然的。 代碼中所有的修改都可歸為這三類,更進(jìn)一步,大部分應(yīng)該是前兩類。開源世界有一個(gè)很好用的工具是Doxygen。它的作用就是把代碼里的特殊注釋抽取出來(lái)變?yōu)槲臋n(一個(gè)類似Latex的工具,非所見即所得的文檔編輯工具)。我們的思路就是,利用Doxygen工具,將代碼和文檔的開發(fā)變?yōu)橥竭^(guò)程。由于文檔含在代碼里,也意味著Doxygen的文檔也是文本,在版本庫(kù)的管理下,能精確的看到每一個(gè)比特的修改。為了不耽誤說(shuō)正事,后面有文章做一個(gè)的Doxygen介紹。這里簡(jiǎn)單的介紹一下Doxygen。 Doxygen 是一個(gè)程序的文檔產(chǎn)生工具,可將程序中的特定注釋轉(zhuǎn)換成為說(shuō)明文件。比如說(shuō)對(duì)于一個(gè) 以上經(jīng)過(guò)Doxygen抽取編譯后,會(huì)生成一個(gè)綜合性文檔,可在里面查到: 即使我們不用doxygen編譯,寫在代碼里的注釋,也是不影響我們理解的。只是編譯后,查閱起來(lái)更方便。 這是我們實(shí)現(xiàn)文檔代碼同源的基礎(chǔ)。但文檔代碼的同源不僅僅是把代碼和文檔合成一個(gè)源代碼文件。我們要做得是: 1.需求要和代碼中的各個(gè)實(shí)現(xiàn)模塊對(duì)應(yīng)起來(lái); 2.文檔的修改、代碼的修改同步進(jìn)行,每天由工程師交叉檢查并給出評(píng)語(yǔ); 3.高級(jí)技術(shù)人員定期整理代碼問(wèn)題,形成案例; 4.如果是公共模塊,項(xiàng)目進(jìn)行過(guò)程中,定期整理其Bug,問(wèn)題,維護(hù)其可用性。 2.1 需求和代碼對(duì)應(yīng) 開發(fā)一款產(chǎn)品,首先要提需求,需求開發(fā)出來(lái),大抵是這樣的: 需求提出了方方面面的要求,一般,需求的分配表也跟在后面,用于指示這個(gè)需求都由那些模塊實(shí)現(xiàn)。 緊接著下來(lái)是軟硬件的概要或者詳細(xì)設(shè)計(jì),有些公司為了節(jié)省,就只有設(shè)計(jì);有的干脆就連設(shè)計(jì)也省了,走“敏捷'路線。這個(gè)并不重要。 Doxygen支持自由頁(yè)面,可以輕松的寫一個(gè)Python的小工具,將excel的需求表轉(zhuǎn)化為 txt的文本文件,被doxygen所識(shí)別。 這樣做得好處: 1.需求只要經(jīng)常用版本庫(kù)追蹤,誰(shuí)改了一個(gè)字,改了什么都會(huì)清清楚楚。 2.程序員查閱需求會(huì)更加簡(jiǎn)便。同時(shí),每日的檢查強(qiáng)調(diào),需求的修改,可能會(huì)帶來(lái)代碼的修改;Bug的修改可能帶來(lái)代碼的修改,需求的修改。從而強(qiáng)調(diào)需求的定義作用,主動(dòng)維護(hù)需求的前后一致。 如模塊中編寫時(shí),說(shuō)明實(shí)現(xiàn)了哪些需求。 這些都是超文本標(biāo)簽,點(diǎn)擊后迅速轉(zhuǎn)到需求定義處可查看。 2.2 每日檢查 該方法的核心內(nèi)容,就是每日檢查。一個(gè)程序員每天的代碼產(chǎn)量最多可達(dá)上千行(非每日平均產(chǎn)量)。如果是更改Bug,可能一天大部分的時(shí)間用于分析跟蹤上。正真的修改并不多。每日提交版本庫(kù)后,由其他程序員或者部門經(jīng)理檢查代碼及修改,檢查的內(nèi)容如下: 1.代碼修改是否有效,符合組織內(nèi)部的規(guī)定; 2.文檔和代碼是否對(duì)應(yīng)。 與需求類似,寫一個(gè)Excel表格,包含:模塊;檢查人;日期;問(wèn)題描述的跟蹤表;檢查完成后提交至版本庫(kù),由對(duì)應(yīng)的工程師承接修改。 每次檢查,檢查文檔、代碼的問(wèn)題,通過(guò)版本庫(kù)可以很輕松的跟蹤相關(guān)的修改。并定位修改是否合理。 2.3 飛行檢查 為了防止檢查流于形式,定期對(duì)一些具有代表性的問(wèn)題做總結(jié)。高級(jí)技術(shù)人員需要做一些飛行檢查,定期的抽查檢查表以及文檔代碼的對(duì)應(yīng)情況。并從問(wèn)題中選出有代表性的案例,收集成案例,用于團(tuán)隊(duì)的提升和警示。 2.4公共模塊 一個(gè)有積累的公司,應(yīng)該不會(huì)從0開始構(gòu)建自己的項(xiàng)目。總是多多少少有些積累的。代碼同源的模塊如何被復(fù)用呢?首先,公司內(nèi)部要有完善的版本控制機(jī)制。任何代碼,全局只有一份。對(duì)于svn的版本庫(kù)、git的版本庫(kù),有不同的辦法。(svn可以使用externals屬性,保持全局唯一的庫(kù)文件。git可以使用subtree, submodule的辦法建立全局唯一的庫(kù)文件。)由于庫(kù)代碼導(dǎo)出后,文檔和庫(kù)跟著走的,也不存在這不對(duì)應(yīng)的問(wèn)題。如果發(fā)生庫(kù)的修改,因?yàn)槿志鸵环輲?kù)的代碼。更改完畢,全局都會(huì)跟著修改。所以,庫(kù)的提交需要更為慎重。需要建立更為嚴(yán)謹(jǐn)?shù)男薷拇_認(rèn)機(jī)制。 無(wú)論怎么更改,只要每天保證文檔、代碼對(duì)應(yīng)。下載最新的源代碼,使用Doxygen編譯,則可得到最新的文檔。 三、補(bǔ)充說(shuō)明 文檔代碼同源的思路,可解決實(shí)踐中的文檔代碼不一致的問(wèn)題,但這不是最終目的。長(zhǎng)期堅(jiān)持,達(dá)到一個(gè)良好的開發(fā)習(xí)慣和開發(fā)氛圍。從而提高項(xiàng)目交付質(zhì)量和內(nèi)部的管理水平。達(dá)到組織和個(gè)人的共同成長(zhǎng)。 四、遺留問(wèn)題 這個(gè)方法,是有適用范圍的,我在軟硬結(jié)合的項(xiàng)目以及一些純軟件的中小型項(xiàng)目上實(shí)施,取得了一些比較好的效果。尚未在比較大型的項(xiàng)目上使用。 另外,方法也需要不少工具配合。 1.如果內(nèi)部沒(méi)有需求管理工具的廠商,可以直接用excel管理,然后自己寫個(gè)python工具轉(zhuǎn)換一下。如果內(nèi)部有需求管理工具的公司,應(yīng)該都可以將需求導(dǎo)出成excel,然后通過(guò)工具轉(zhuǎn)換成doxygen接受的文檔。 2.內(nèi)部的檢查一定要每天堅(jiān)持,這才是核心中的核心。每天并不耗時(shí),但是卻很重要,量變引起質(zhì)變。 3.庫(kù)的管理需要svn、git等版本控制工具的強(qiáng)力支持,這個(gè)需要被管理公司有一定的版本管控水平和能力。 最后,文檔中提到的方法和工具,歡迎與我討論。我會(huì)陸續(xù)的將一些工具方法整理出來(lái)發(fā)給大家。 |
|
來(lái)自: 黃爸爸好 > 《業(yè)務(wù)》