| ||||||||
目錄摘要本文以cvs為例,介紹了軟件工程中,編碼過(guò)程中對于版本控制的運用的一些技巧。在最后部分,還介紹了軟件工程最后的“交付工程”。 問(wèn)題的提出編碼過(guò)程是軟件工程的重要一環(huán)。這一部分工作的好壞直接關(guān)系到軟件產(chǎn)品的質(zhì)量。高效率的多人協(xié)作開(kāi)發(fā),依賴(lài)于團隊精神、設計師對于軟件架構的整體把握、好的并行版本控制技術(shù),以及制度化的每日構建和最后階段的交付工程。 今年六月,我有幸在一家開(kāi)發(fā)安全軟件的公司觀(guān)摩了他們的每日構建和交付工程中的活動(dòng)。他們對于并行版本控制、每日構建技術(shù)熟練而深入的應用給我留下了非常深刻的印象。在此,我愿與讀者一同分享我自己的學(xué)習體會(huì ),這其中的某些部分得益于在那家公司的實(shí)地觀(guān)摩,另一些則來(lái)自于我自己參加的實(shí)際軟件工程項目的體會(huì )。 毫無(wú)疑問(wèn)地,一個(gè)軟件工程項目最有價(jià)值的部分還是在它的設計階段。良好的設計能夠讓實(shí)現環(huán)節變得更有效率,從而極大地提高勞動(dòng)生產(chǎn)率;而好的編碼規范,則是協(xié)同開(kāi)發(fā)的重要基石。限于篇幅,對于前述兩項內容本文將不會(huì )過(guò)多設計,我將著(zhù)重介紹軟件工程中編碼與測試環(huán)節的一些經(jīng)驗,這些經(jīng)驗對于已經(jīng)擁有優(yōu)秀的軟件設計師和編程、測試人員,而苦于由于連調、最終測試導致發(fā)布頻頻延期的開(kāi)發(fā)團隊來(lái)說(shuō)是非常有益的。 并行版本控制——多人協(xié)作開(kāi)發(fā)的有效保障設想一個(gè)有4名編程人員的小型開(kāi)發(fā)團隊(以下簡(jiǎn)稱(chēng)“TJRP開(kāi)發(fā)組”),Tom、Jason、Robert和Pat分別負責4個(gè)模塊,按照傳統的軟件開(kāi)發(fā)模式,開(kāi)發(fā)將經(jīng)歷編程-連調-測試-發(fā)布4個(gè)階段。 如果最初的設計正確,并且,四個(gè)開(kāi)發(fā)人員都是Guru級的程序員而且配合默契,那么這個(gè)模式將會(huì )運轉良好。然而遺憾的是,Pat剛剛參加工作不久,對于設計師撰寫(xiě)的設計文檔的理解不夠透徹,而Robert則自作主張地對設計進(jìn)行了一些修正,更糟糕的是,項目組會(huì )議的時(shí)候,這些問(wèn)題沒(méi)有及時(shí)地被暴露出來(lái),導致Pat和Robert代碼在設計上的“分歧”越來(lái)越大。結果,進(jìn)入連調的階段,Pat和Robert發(fā)生了激烈的爭執,在吵得不可開(kāi)交之后,項目經(jīng)理終于讓4個(gè)人坐到了一起來(lái)解決問(wèn)題,最后,連調階段整整多花了一倍的時(shí)間。 但倒霉的事情還沒(méi)有結束。Jason在測試中發(fā)現,原本正常的代碼的行為被改變了,并且,他驚訝地發(fā)現代碼被某個(gè)“別人”改過(guò),在翻箱倒柜地找出某份正常版本的副本之后,他又發(fā)現,“別人”修改中的某些地方是必要的。代碼合并和重新測試使得測試階段足足花掉了原先預想3倍的時(shí)間。 可憐的Tom運氣更差,作為主要的代碼復審人員,他不得不閱讀所有的代碼。Robert和Pat的爭吵導致了大量的代碼變動(dòng),他不得不重新審核代碼,而Jason的代碼合并引發(fā)的新問(wèn)題又讓他不得不分神去幫助Jason進(jìn)行調整。 最后的結果是,軟件開(kāi)發(fā)的成本是預期的2.4倍,發(fā)布時(shí)間也拖后了不少。我并不是在開(kāi)玩笑,上面所講的是一個(gè)發(fā)生在那家安全軟件公司的真實(shí)故事。他們的技術(shù)經(jīng)理介紹,在施行了規范的開(kāi)發(fā)制度,以及啟用并行版本控制系統之后,他們認為開(kāi)發(fā)達到了一個(gè)全新的水平。并行版本控制系統本身并沒(méi)有產(chǎn)生任何代碼,但由于使用這樣的系統,開(kāi)發(fā)的效率被大大地提高了。 所謂版本控制其實(shí)并不是什么復雜的概念。對于開(kāi)發(fā)活動(dòng)的絕大多數參與者來(lái)說(shuō),版本控制系統在某種意義上能夠幫助他們做好開(kāi)發(fā)過(guò)程中的記錄工作,并且,通過(guò)保存文件在不同時(shí)期的版本,交付工程師和代碼復審員能夠很容易地縮小搜索問(wèn)題代碼的范圍,而程序員則可以通過(guò)這樣的系統更好地并行協(xié)作。一般來(lái)說(shuō),源代碼的版本控制系統能夠實(shí)現以下一些最基本的功能:
我們知道,技術(shù)不是解決一切問(wèn)題的靈丹妙藥,但是誰(shuí)也不會(huì )否認大規模的機械化生產(chǎn)的效率高于人拉肩扛的手工業(yè)作坊,一旦運用得當,技術(shù)將極大地改善我們的工作和生活。我們可以看到,上面的功能有效地解決了TJRP開(kāi)發(fā)組所面臨的絕大部分問(wèn)題,例如:
更進(jìn)一步,以管理者的角度,還有了一些額外的好處,如:
我們可以看到,上述改進(jìn)集中地體現了一個(gè)重要的思想,即:
下面我們將以非常常見(jiàn)的版本控制系統——cvs[1]為例,介紹并行版本系統一些基本的使用原理。 代碼提交和同步——從update和commit說(shuō)起每當我們開(kāi)始一個(gè)新的修改之前,首先要做的是從代碼庫中提取出一份最新的副本(通過(guò)update操作完成);在本地修改、粗調之后,則應盡快將代碼提交回代碼庫(通過(guò)commit操作完成)。 基本的update和commit操作流程如下圖所示: ![]() 圖1. cvs update和commit 這兩項操作也解決了日常開(kāi)發(fā)大約80%的問(wèn)題。絕大多數情況下,這部分的工作是相當簡(jiǎn)單的,除非出現兩個(gè)開(kāi)發(fā)者同時(shí)修改同一個(gè)文件的情況,例如,兩個(gè)開(kāi)發(fā)者同時(shí)地修改了同一個(gè)文件的同一個(gè)版本,這種情形稱(chēng)為沖突: ![]() 圖2. cvs并行開(kāi)發(fā)中的沖突 可能開(kāi)發(fā)者B的動(dòng)作比較快,或者,修改的東西比較簡(jiǎn)單,于是他首先提交。在A(yíng)、B從代碼庫中提取代碼時(shí),最新版本是1.1,于是,B提交的版本被版本控制系統命名為1.2。 但不久,A想要提交代碼,版本控制系統將拒絕他的提交,因為他的修改基于代碼的1.1版,而目前的最新版本已經(jīng)是1.2了。cvs提供了自動(dòng)合并功能,允許在兩個(gè)人修改的不是同一行代碼的前提下,自動(dòng)合并本地修改和最新的代碼,當然,如果趕上兩個(gè)人同時(shí)修改同一行代碼的情況,cvs也會(huì )非常“聰明”地把兩個(gè)“英雄所見(jiàn)略同”的地方合并。 但如果兩個(gè)人恰好都修改了同一行代碼,而且改的不一樣怎么辦?cvs會(huì )告訴后一個(gè)提交的開(kāi)發(fā)者發(fā)生了這樣的情況,并且要求他解決問(wèn)題。代碼中存在的差異將以<<<和>>>標記出來(lái),以方便進(jìn)行修改。 簡(jiǎn)單說(shuō)來(lái),當發(fā)生沖突時(shí),我們通常約定由后一個(gè)提交者解決沖突——當然,他可以選擇忽略這些沖突,但這些操作都會(huì )被記錄,更何況,統計顯示,同時(shí)將一行代碼修改為兩種不同的樣子這樣的情況在實(shí)際開(kāi)發(fā)中很少出現。于是,修改流程繼續,如下圖: ![]() 圖3. 開(kāi)發(fā)者A解決沖突,并提交 極端情況下,可能出現多個(gè)開(kāi)發(fā)者同時(shí)修改同一個(gè)文件的問(wèn)題。這一問(wèn)題基本上可以按照上述的方法解決。當然,為了避免發(fā)生這樣的情形,在設計的時(shí)候就應該讓每個(gè)人工作的代碼盡可能地不重疊。 下面是非?;镜腸vs update/commit操作規范:
同步代碼(update)和提交代碼(commit)占到了cvs日常操作的80%以上。從上面的介紹我們可以看出,僅僅依靠這兩項非常簡(jiǎn)單的功能,cvs就能極大地改善開(kāi)發(fā)流程,并提高軟件工程的可控性。簡(jiǎn)單地說(shuō):
編碼過(guò)程中的溝通紐帶——commit mailcvs是一項開(kāi)放性很強的工具,它可以被非常容易地訂制。一般來(lái)說(shuō),cvs服務(wù)器會(huì )架設在一臺Unix主機上(我們推薦使用FreeBSD),通過(guò)使用腳本語(yǔ)言(例如,Perl),cvs能夠完成一些額外的功能。 commit mail是commit log在郵件系統上的延伸。下面是一封典型的commit mail,它來(lái)自FreeBSD開(kāi)發(fā)團隊:
我們看到,上面的這封commit mail中提到了開(kāi)發(fā)者(phk)、提交時(shí)間(太平洋時(shí)間2003年10月21日23:32:20)、涉及的代碼庫名字(FreeBSD src repository)、修改過(guò)的文件(sys/geom的geom_io.c)以及commit log。最后,commit log還提到了提交后文件的最新版本(1.50),修改規模(+3 -6)以及代碼的實(shí)際路徑。 實(shí)現上面的功能并不復雜,實(shí)際上,您只需要下載一套經(jīng)過(guò)定制的FreeBSD cvs代碼庫(壓縮包不超過(guò)40KB),并作少量的調整,就能夠直接使用這些功能(我們將在不久以后發(fā)布這些內容)。進(jìn)行這些訂制甚至不需要基本的Perl和C/C++常識就能夠完成——當然,我想這樣的常識對于軟件開(kāi)發(fā)人員來(lái)說(shuō),并不算是很高的要求。 commit mail可以通過(guò)郵件列表發(fā)給全體開(kāi)發(fā)者。許多大的軟件公司,以及開(kāi)放源代碼團體,都采用這樣的方式來(lái)協(xié)調開(kāi)發(fā)活動(dòng)。 日常測試——堅持每日構建傳統的軟件工程中,測試發(fā)生在連調之后。這么做的理論依據是,測試依賴(lài)于一份一致的、至少能夠正常編譯并啟動(dòng)的代碼。而這個(gè)條件在連調之前是無(wú)法滿(mǎn)足的。 然而在有了版本控制系統(如, cvs)之后,連調變成了開(kāi)發(fā)中的日常行為。代碼幾乎在每一時(shí)刻都處于高度的一致?tīng)顟B(tài),甚至在許多時(shí)候,代碼會(huì )處于可用狀態(tài),從而為測試創(chuàng )造非常有利的條件。 許多大型開(kāi)發(fā)團隊會(huì )使用一臺甚至多臺被稱(chēng)作TinderBox的機器來(lái)完成每日構建和測試。簡(jiǎn)單的每日構建流程如下:
其中,第一、二步是可以通過(guò)腳本定時(shí)、自動(dòng)完成的,不需要人工干預。第三步中的編譯錯誤在軟件開(kāi)發(fā)中偶爾會(huì )發(fā)生(這可能來(lái)自于沖突合并時(shí)引發(fā)的問(wèn)題,但由于開(kāi)發(fā)人員的本地測試,這種文體不會(huì )是經(jīng)常性的),習慣上,這些錯誤會(huì )由代碼復審員去追蹤和處理,并交給相關(guān)的開(kāi)發(fā)人員解決。 測試工程師可以將編譯好的版本交付給一個(gè)測試組,甚至用戶(hù)去進(jìn)行測試。測試工程師可能隨時(shí)發(fā)布軟件的“快照”版本。 實(shí)際上在許多大公司中,每日構建是非常“家常便飯”的事情。我們看到的Internet Explorer版本,如6.0.2600或者類(lèi)似6.0 Build 2600中的2600的意思就是這份代碼之前已經(jīng)經(jīng)歷了2600次每日構建操作(當然,中間肯定進(jìn)行過(guò)不少修改,而且,也不排除這個(gè)2600是故意湊整得到的,但總之,他們進(jìn)行了相當多的日常構建工作)。 在軟件開(kāi)發(fā)的后期,由于發(fā)布的迫在眉睫,每日構建很可能會(huì )演化為持續構建,即,每次commit觸發(fā)一次構建操作。所有問(wèn)題立即得到反饋。 為了支持每日構建或持續構建,比較理想的方法是采用Makefile完成構建操作。對于Unix系統,make工具通常是pmake(BSD Make)或gmake(GNU Make);對于Visual C++,則是nmake。大的開(kāi)發(fā)團體通常使用一組腳本來(lái)完成所有的make操作,而對于中小型項目,手工地使用類(lèi)似VC++這樣的IDE本身的構建功能也是可以接受的。 基本的每日構建規范如下:
作為commit mail的有效補充,許多項目開(kāi)發(fā)組會(huì )建立郵件列表來(lái)傳遞一些相關(guān)的信息。測試日報通常會(huì )發(fā)給整個(gè)開(kāi)發(fā)團隊的參加人員,此外,保留一個(gè)出現過(guò)的問(wèn)題記錄,對于測試環(huán)節也會(huì )有相當大的好處——這些問(wèn)題在隨后被反復測試,以保證最終的RELEASE不出現這些問(wèn)題。 每日構建并不是可有可無(wú)的工作,作為日常測試的重要手段,每日構建能夠有效地幫助管理者了解工程進(jìn)度,幫助開(kāi)發(fā)者盡早發(fā)現問(wèn)題,同時(shí),也會(huì )促進(jìn)開(kāi)發(fā)組中的交流。 有效的版本控制——版本標記、代碼分支三個(gè)文件的“最新版本”分別是1.5, 1.3, 1.4,但最新版本不一定是我們需要的。在這種情況下,版本控制系統提供了一個(gè)非常重要的機制——版本標記。例如,我們目前已經(jīng)確認三個(gè)文件的1.4, 1.3, 1.4組合在一起能夠正常運行,于是我們在三個(gè)文件的這些版本上標注標記TAG_1,如下圖: ![]() 圖4. TAG_1標記被打到三個(gè)文件的不同版本上 需要說(shuō)明的是,標記是可以被移動(dòng)的。這意味著(zhù)一旦發(fā)現標記打錯了,可以把標記移動(dòng)到別的位置。但在實(shí)踐中,標記往往同另一個(gè)非常重要的版本控制機制——代碼分支一起使用。在詳細討論標記(tag)的重要意義之前,我們先來(lái)看看代碼分支時(shí)什么: ![]() 圖5. 比較復雜的情形,一個(gè)正在開(kāi) 所謂代碼分支是版本控制中的一個(gè)非常關(guān)鍵的概念。當開(kāi)發(fā)到某個(gè)階段的時(shí)候,可以交付一個(gè)版本,而主要的開(kāi)發(fā)者則把精力投入到最新版本的開(kāi)發(fā)中。第一個(gè)交付分支(2.0)中的一些問(wèn)題,以及引入的新功能隨后在RELENG_2分支中被修正,公司決定發(fā)布2.1版本;此后,2.x中的問(wèn)題繼續在RELENG_2中被修正,而一些安全更新,則被合并到2.1-RELEASE中(RELENG_2_1)。 圖5展示的是一個(gè)文件上的版本分支。實(shí)際的軟件工程項目的源代碼會(huì )由大量文件組成,盡管在本質(zhì)上分支是針對每一個(gè)文件說(shuō)的,但在被標注了同一分支名稱(chēng)的文件,就像版本標記一樣,能夠表達一組特定版本文件的集合。 cvs的版本分支功能有一個(gè)很大的缺陷,即,大量文件的切分點(diǎn)(Branchpoint, 即某一個(gè)分支最初的版本號)在cvs中很難被指定(cvs支持按某一分支、某一特定時(shí)間、某一特定版本來(lái)提取文件,但通常不同的文件的版本號并不統一,特別是在大型項目中,肯定有某些文件因為被提交的次數很多,而版本號很“高”的情況)。為了消除這個(gè)缺陷,在實(shí)踐上,我們采用版本標記與分支結合的方法,即,在劃分新的分支之后,在這一分支的這些文件的版本上增加一個(gè)版本標記。 例如:對于軟件的2.0版,在劃分時(shí),將切分出RELENG_2(2.x),RELENG_2_0(2.0)兩個(gè)分支,而這時(shí)的文件的版本,同時(shí)被打上一個(gè)RELENG_2_0_0_BP的標記。這樣一來(lái),在以后比較版本時(shí),我們可以使用RELENG_2_0_0_BP來(lái)指定這個(gè)版本。當不同的分支又增加了許多修改之后,這個(gè)標記將極大地減輕代碼復審員的工作量。 注意,代碼分支并不僅限于版本上的用法。事實(shí)上,基于同一代碼基礎的多個(gè)不同的軟件也可以采用代碼分支的方法進(jìn)行開(kāi)發(fā)。而最終,這些代碼還可以合并為一個(gè)。 您可能已經(jīng)注意到最左邊的一組版本序列:1.1, 1.2, 1.3, 1.4, 1.5. 1.6。在cvs中,這一序列被稱(chēng)為“主分支(MAIN Branch)”。盡管并非必須,但習慣上,主分支通常是活躍的開(kāi)發(fā)分支。在這個(gè)分支中,人們不斷地引入最新的特性,當然,不可避免地,這也可能引發(fā)一些問(wèn)題,而這些引入主分支的問(wèn)題在隨后將被追蹤、修訂。經(jīng)過(guò)一段時(shí)間之后,被“沉淀”下來(lái)的代碼可以進(jìn)入另一個(gè)叫做“穩定分支”的代碼系。 這樣的開(kāi)發(fā)模式通常被稱(chēng)作“多頭并進(jìn)”模式,這樣的模式在許多開(kāi)放源代碼的軟件開(kāi)發(fā)中非常常見(jiàn),例如,Linux的單、雙號版本、FreeBSD的-STABLE和-CURRENT[2],等等。在一般的商業(yè)軟件開(kāi)發(fā)中,這種模式也相當常見(jiàn),特別是在大公司的開(kāi)發(fā)中。擁有多頭并進(jìn)這一能力對于大型軟件的開(kāi)發(fā)尤為重要,因為大型軟件很可能包含相當多的模塊,通過(guò)版本控制,問(wèn)題能夠很容易地被整個(gè)開(kāi)發(fā)團隊追蹤。 多頭并進(jìn)的開(kāi)發(fā)環(huán)境中,開(kāi)發(fā)人員可以在粗略熟悉了某個(gè)分支的代碼體系的情況下參與開(kāi)發(fā)或維護,這意味著(zhù),即使某個(gè)代碼分支的維護人員突然離去,其他人也不用擔心通盤(pán)閱讀不同分支的代碼可能造成的理解困難,換言之,對于新的維護人員的要求被降低,從而,軟件的開(kāi)發(fā)和維護過(guò)程能夠更為有序地進(jìn)行。 據我所知,FreeBSD的軟件開(kāi)發(fā)過(guò)程極大地得益于多頭并進(jìn)的開(kāi)發(fā)模式。下面簡(jiǎn)單地介紹一下FreeBSD所采用的軟件開(kāi)發(fā)模式:
事實(shí)上,上述開(kāi)發(fā)模式已經(jīng)被證明是相當成功的。由于開(kāi)發(fā)過(guò)程中每一天都有相當多的人對新的CURRENT和STABLE分支的代碼進(jìn)行測試,因此,在最近的幾年中,FreeBSD的開(kāi)發(fā)一直呈現著(zhù)良好的態(tài)勢。 交付工程(Release Engineering)基礎——特性?xún)鼋Y和代碼凍結許多參與過(guò)大型項目開(kāi)發(fā)的讀者可能都經(jīng)歷,至少是聽(tīng)說(shuō)過(guò)特性?xún)鼋Y和代碼凍結這樣一個(gè)概念。所謂“特性?xún)鼋Y”實(shí)際上是一個(gè)開(kāi)發(fā)者之間的約定,在這個(gè)階段中,不再允許添加新的功能。 特性?xún)鼋Y(Feature Freeze)通常在一個(gè)開(kāi)發(fā)分支(Development Branch)躍變?yōu)榻桓斗种?Release Branch)的時(shí)候開(kāi)始。之所以需要特性?xún)鼋Y,是因為增加新的特性很有可能引入新的問(wèn)題,而這將給代碼復審帶來(lái)沉重的負擔,甚至導致一次不成功的最后交付。 當然,對于那些已經(jīng)明確地定義了特性表的小型軟件工程項目(例如,傳統的瀑布開(kāi)發(fā)模型)來(lái)說(shuō),特性?xún)鼋Y沒(méi)有什么意義,因為在這些工程中,詳細設計完全是在編寫(xiě)代碼之前進(jìn)行的,這意味著(zhù),代碼將要寫(xiě)成什么樣子已經(jīng)在詳細設計中明確地定義。但在實(shí)際的項目中,詳細設計往往會(huì )包括兩類(lèi)不同的類(lèi)型要求——一部分是“必須實(shí)現的特性(Must have feature)”,另一部份則是“希望實(shí)現的特性(Desired Feature)”。在交付之前,所有“希望實(shí)現的特性”都會(huì )在特性?xún)鼋Y時(shí)被明確成“實(shí)現特性”和“不實(shí)現特性”。 我們注意到,這種情況下,某些特性被延遲到接近交付的時(shí)候才被明確成“必須實(shí)現”,而另一些“希望實(shí)現的功能”則被作為“不實(shí)現”,從而轉化為我們先前熟悉的樣子,即詳細設計文檔中明確地定義了軟件中的所有特性。 這樣做的結果是軟件工程項目具有更大的靈活性。由客戶(hù)需求產(chǎn)生的功能設計,很顯然地,應該列為“必須實(shí)現的特性”,而那些開(kāi)發(fā)團隊提出的能夠提高軟件整體可擴展性、可伸縮性或其他性能的特性,則應列為“希望實(shí)現的特性”。在特性?xún)鼋Y之后,整個(gè)開(kāi)發(fā)團隊將專(zhuān)注于那些“實(shí)現特性”(盡管這些特性可能還沒(méi)有被正式的實(shí)現)更加穩定,從而將生產(chǎn)出更高質(zhì)量的軟件。 根據我個(gè)人的經(jīng)驗,特性?xún)鼋Y應該發(fā)生在預期編碼時(shí)間已經(jīng)用去大約2/3的時(shí)候。這時(shí),項目經(jīng)理應該組織開(kāi)發(fā)人員舉行一次會(huì )議討論特性?xún)鼋Y,而在特性?xún)鼋Y之后,在軟件正式交付之前,任何開(kāi)發(fā)人員都不應該再去考慮那些被列為“不實(shí)現特性”的功能。 代碼凍結是一個(gè)與特性?xún)鼋Y類(lèi)似的概念,在這個(gè)階段,只允許對被凍結代碼分支中的錯誤進(jìn)行修正,而不允許任何其他的、涉及功能的修改。實(shí)踐上,這個(gè)過(guò)程中,只有交付工程師(通常是一個(gè)或多個(gè)對于整個(gè)系統架構非常了解的、有豐富開(kāi)發(fā)經(jīng)驗的代碼復審員)被授予審查和批準代碼提交的權力,任何代碼修改,只要沒(méi)有經(jīng)過(guò)交付工程師的批準,就不能被提交到代碼庫中。 代碼凍結的時(shí)間一般不需要太長(cháng)。對于中等規模的項目,這一過(guò)程通常會(huì )持續一至兩周,對于大型項目,這一過(guò)程則有可能持續一個(gè)月甚至更長(cháng)的時(shí)間。在這個(gè)階段,交付工程師主要負責代碼復審,而測試工程師則有責任及時(shí)反饋集中的測試中暴露出的問(wèn)題,并與相關(guān)的開(kāi)發(fā)人員聯(lián)系、解決這些問(wèn)題。 技術(shù)上,代碼凍結可以通過(guò)修改cvs中的配置來(lái)實(shí)現。不過(guò),更好的辦法是通過(guò)制度來(lái)保證代碼凍結。 交付工程——編碼階段的總結交付工程的好壞在某種意義上,是直接關(guān)系到用戶(hù)利益的部分。前面已經(jīng)說(shuō)了相當多的關(guān)于軟件開(kāi)發(fā)過(guò)程中通過(guò)版本控制技術(shù)來(lái)提高開(kāi)發(fā)效率的技巧和方法,這里我將繼續說(shuō)一說(shuō)交付工程。 前面提到了每日構建中在代碼上適當地打上版本標記,以及在劃分版本分支時(shí)在切分點(diǎn)上增加版本標記,這些對于交付工程都具有非常重要的意義。交付工程,在軟件工程項目中是一個(gè)融合了代碼復審和集中測試的重要階段。
一些讀者可能已經(jīng)注意到,交付工程的絕大多數任務(wù)事實(shí)上已經(jīng)被融入了我前面所描述的開(kāi)發(fā)過(guò)程——在編碼階段的整個(gè)過(guò)程中,代碼復審、問(wèn)題反饋和測試一直是持續地進(jìn)行的,只是,在“交付工程”階段,代碼復審和測試被提升到了一個(gè)更為核心的地位,在這一階段,開(kāi)發(fā)的重要任務(wù)是查錯和排錯,而不再是將軟件的功能推向一個(gè)嶄新的水平。 總結——基于版本控制、每日構建的編碼過(guò)程前面我們已經(jīng)介紹了通過(guò)引入版本控制系統改善軟件工程中編碼和測試階段過(guò)程的一些方法。這些方法來(lái)自于我本人所參與的,以及通過(guò)一些其他途徑了解到的實(shí)際項目的開(kāi)發(fā)經(jīng)驗。文中介紹的內容以cvs (Concurrent Version System)為主,這是因為cvs比較容易得到(它本身是開(kāi)放源代碼軟件),并且,比較成熟。另外,由于關(guān)于cvs本身的細節并沒(méi)有涉及很深,因此,讀者也很容易將這些經(jīng)驗套用在其他版本控制系統,如Bit Keeper, Perforce, Clear Case等等之上。 引入版本控制、每日構建之后,項目管理人員和開(kāi)發(fā)者可以明顯地感受到以下改善:
最后,讓我們用圖片的形式,重新描述一下上面的那些過(guò)程: ![]() 圖6. 日常開(kāi)發(fā)過(guò)程 ![]() 圖7. 交付工程 這樣,我們已經(jīng)粗淺地討論了關(guān)于并行版本控制技術(shù)如何改變軟件開(kāi)發(fā)過(guò)程的一些大致的方法,以及其中的一些先進(jìn)思想。在文中我盡可能地回避了類(lèi)似cvs系統的操作具體細節,并且,避開(kāi)了一些cvs特有的功能?;旧?,本文中提供的方法,特別是其中的一些思想,能夠適應任何一種版本控制系統,因此,這些方法具有相當大的普遍意義。 參考文獻[1] CVS - 并行版本系統 http://www.cvshome.org 李鑫,北京工業(yè)大學(xué)計算機學(xué)院2000級學(xué)生,目前擔任計算機學(xué)院學(xué)生科協(xié)主席、放飛技術(shù)網(wǎng)技術(shù)總監。您可以通過(guò)電子郵件 ( delphij@frontfree.net 與他聯(lián)系 )。 版權聲明 本文版權歸原作者和放飛技術(shù)網(wǎng)共同所有,轉載本文必須同我們聯(lián)系并獲得同意(書(shū)面或PGP簽署的許可)。 | ||||||||
聯(lián)系客服