久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

協(xié)作開發(fā)中的質(zhì)量保證技術(shù)——并行版本控制,、每日構(gòu)建和交付工程

 douli 2005-08-20
協(xié)作開發(fā)中的質(zhì)量保證技術(shù)——并行版本控制,、每日構(gòu)建和交付工程
原創(chuàng):司徒彥南 2003年10月29日

目錄

  • 摘要
  • 問題的提出
  • 并行版本控制——多人協(xié)作開發(fā)的有效保障
  • 代碼提交和同步
  • 編碼過程中的溝通紐帶——commit mail
  • 日常測試——每日構(gòu)建
  • 有效的版本控制——代碼分支、版本標記
  • 特性凍結(jié)與代碼凍結(jié)
  • 交付工程
  • 總結(jié)
  • 參考文獻
  • 作者簡介
  • 摘要

    本文以cvs為例,,介紹了軟件工程中,,編碼過程中對于版本控制的運用的一些技巧,。在最后部分,還介紹了軟件工程最后的“交付工程”,。

    問題的提出

    編碼過程是軟件工程的重要一環(huán),。這一部分工作的好壞直接關(guān)系到軟件產(chǎn)品的質(zhì)量。高效率的多人協(xié)作開發(fā),,依賴于團隊精神,、設(shè)計師對于軟件架構(gòu)的整體把握、好的并行版本控制技術(shù),,以及制度化的每日構(gòu)建和最后階段的交付工程,。

    今年六月,我有幸在一家開發(fā)安全軟件的公司觀摩了他們的每日構(gòu)建和交付工程中的活動,。他們對于并行版本控制,、每日構(gòu)建技術(shù)熟練而深入的應(yīng)用給我留下了非常深刻的印象。在此,,我愿與讀者一同分享我自己的學習體會,,這其中的某些部分得益于在那家公司的實地觀摩,另一些則來自于我自己參加的實際軟件工程項目的體會,。

    毫無疑問地,,一個軟件工程項目最有價值的部分還是在它的設(shè)計階段。良好的設(shè)計能夠讓實現(xiàn)環(huán)節(jié)變得更有效率,,從而極大地提高勞動生產(chǎn)率,;而好的編碼規(guī)范,則是協(xié)同開發(fā)的重要基石,。限于篇幅,,對于前述兩項內(nèi)容本文將不會過多設(shè)計,我將著重介紹軟件工程中編碼與測試環(huán)節(jié)的一些經(jīng)驗,,這些經(jīng)驗對于已經(jīng)擁有優(yōu)秀的軟件設(shè)計師和編程,、測試人員,而苦于由于連調(diào),、最終測試導(dǎo)致發(fā)布頻頻延期的開發(fā)團隊來說是非常有益的,。

    并行版本控制——多人協(xié)作開發(fā)的有效保障

    設(shè)想一個有4名編程人員的小型開發(fā)團隊(以下簡稱“TJRP開發(fā)組”),Tom,、Jason,、Robert和Pat分別負責4個模塊,按照傳統(tǒng)的軟件開發(fā)模式,,開發(fā)將經(jīng)歷編程-連調(diào)-測試-發(fā)布4個階段,。

    如果最初的設(shè)計正確,并且,,四個開發(fā)人員都是Guru級的程序員而且配合默契,,那么這個模式將會運轉(zhuǎn)良好,。然而遺憾的是,Pat剛剛參加工作不久,,對于設(shè)計師撰寫的設(shè)計文檔的理解不夠透徹,,而Robert則自作主張地對設(shè)計進行了一些修正,更糟糕的是,,項目組會議的時候,,這些問題沒有及時地被暴露出來,導(dǎo)致Pat和Robert代碼在設(shè)計上的“分歧”越來越大,。結(jié)果,,進入連調(diào)的階段,Pat和Robert發(fā)生了激烈的爭執(zhí),,在吵得不可開交之后,,項目經(jīng)理終于讓4個人坐到了一起來解決問題,最后,,連調(diào)階段整整多花了一倍的時間,。

    但倒霉的事情還沒有結(jié)束。Jason在測試中發(fā)現(xiàn),,原本正常的代碼的行為被改變了,,并且,他驚訝地發(fā)現(xiàn)代碼被某個“別人”改過,,在翻箱倒柜地找出某份正常版本的副本之后,,他又發(fā)現(xiàn),“別人”修改中的某些地方是必要的,。代碼合并和重新測試使得測試階段足足花掉了原先預(yù)想3倍的時間,。

    可憐的Tom運氣更差,作為主要的代碼復(fù)審人員,,他不得不閱讀所有的代碼,。Robert和Pat的爭吵導(dǎo)致了大量的代碼變動,他不得不重新審核代碼,,而Jason的代碼合并引發(fā)的新問題又讓他不得不分神去幫助Jason進行調(diào)整。

    最后的結(jié)果是,,軟件開發(fā)的成本是預(yù)期的2.4倍,,發(fā)布時間也拖后了不少。我并不是在開玩笑,,上面所講的是一個發(fā)生在那家安全軟件公司的真實故事,。他們的技術(shù)經(jīng)理介紹,在施行了規(guī)范的開發(fā)制度,,以及啟用并行版本控制系統(tǒng)之后,,他們認為開發(fā)達到了一個全新的水平,。并行版本控制系統(tǒng)本身并沒有產(chǎn)生任何代碼,但由于使用這樣的系統(tǒng),,開發(fā)的效率被大大地提高了,。

    所謂版本控制其實并不是什么復(fù)雜的概念。對于開發(fā)活動的絕大多數(shù)參與者來說,,版本控制系統(tǒng)在某種意義上能夠幫助他們做好開發(fā)過程中的記錄工作,,并且,通過保存文件在不同時期的版本,,交付工程師和代碼復(fù)審員能夠很容易地縮小搜索問題代碼的范圍,,而程序員則可以通過這樣的系統(tǒng)更好地并行協(xié)作。一般來說,,源代碼的版本控制系統(tǒng)能夠?qū)崿F(xiàn)以下一些最基本的功能:

    • 保存任意一個源代碼文件的不同版本
    • 記錄修改者,、修改原因
    • 當兩個用戶同時修改一個文件時,盡可能地自動合并修改,;在不能合并時,,給出提示
    • 比較不同版本之間,或與本地副本之間的差異
    • 獲取最新版本的全部源代碼供測試,,并允許回退到所保存的源代碼的任意版本
    • 創(chuàng)建代碼分支,,便于軟件發(fā)布和后期維護(后面將會提到);新的代碼可以合并到這些分支中,。
    • 對不同的源代碼給出標記,,方便日后審查
    • 訪問控制:阻止未經(jīng)授權(quán)的修改和查閱

    我們知道,技術(shù)不是解決一切問題的靈丹妙藥,,但是誰也不會否認大規(guī)模的機械化生產(chǎn)的效率高于人拉肩扛的手工業(yè)作坊,,一旦運用得當,技術(shù)將極大地改善我們的工作和生活,。我們可以看到,,上面的功能有效地解決了TJRP開發(fā)組所面臨的絕大部分問題,例如:

    • 由于能夠同時修改代碼,,并獲取對方的修改,,Pat和Robert能夠有效地、盡早地進行溝通
    • 促進開發(fā)者之間的交流,,每一個修改都必須給出原因,,并記錄提交者
    • 測試和連調(diào)可以盡早開始,避免模塊之間的不兼容在最后階段被暴露出來而阻礙發(fā)布
    • 不同開發(fā)者的修改能夠及時合并,,并避免由于版本不一致導(dǎo)致的沖突
    • 代碼復(fù)審可以針對某一代碼分支進行,,從而,允許一些開發(fā)者持續(xù)地開發(fā)下一個版本,,而穩(wěn)定的代碼則可以交付給用戶

    更進一步,,以管理者的角度,,還有了一些額外的好處,如:

    • 每日構(gòu)建和測試能夠讓項目經(jīng)理更好地把握工程的進度
    • 誰作了多少工作,,誰工作的更出色,,可以在版本控制系統(tǒng)中清晰地體現(xiàn)
    • 分工明確,通過訪問控制,,可以避免不了解整個代碼體系的開發(fā)人員偶然的錯誤修改導(dǎo)致的全盤崩潰
    • 更重要地,,版本控制系統(tǒng)中將保持大量的開發(fā)經(jīng)驗,這對于一個開發(fā)團隊來說是一筆無價的財富

    我們可以看到,,上述改進集中地體現(xiàn)了一個重要的思想,,即:

    及時溝通以預(yù)防問題的出現(xiàn);盡早發(fā)現(xiàn),、盡早解決問題,;明確獎懲制度,激發(fā)開發(fā)人員的積極性,。

    下面我們將以非常常見的版本控制系統(tǒng)——cvs[1]為例,,介紹并行版本系統(tǒng)一些基本的使用原理。

    代碼提交和同步——從update和commit說起

    每當我們開始一個新的修改之前,,首先要做的是從代碼庫中提取出一份最新的副本(通過update操作完成),;在本地修改、粗調(diào)之后,,則應(yīng)盡快將代碼提交回代碼庫(通過commit操作完成),。

    基本的update和commit操作流程如下圖所示:


    圖1. cvs update和commit

    這兩項操作也解決了日常開發(fā)大約80%的問題。絕大多數(shù)情況下,,這部分的工作是相當簡單的,,除非出現(xiàn)兩個開發(fā)者同時修改同一個文件的情況,例如,,兩個開發(fā)者同時地修改了同一個文件的同一個版本,,這種情形稱為沖突:

    圖2. cvs并行開發(fā)中的沖突

    可能開發(fā)者B的動作比較快,或者,,修改的東西比較簡單,,于是他首先提交。在A,、B從代碼庫中提取代碼時,,最新版本是1.1,于是,,B提交的版本被版本控制系統(tǒng)命名為1.2。

    但不久,,A想要提交代碼,,版本控制系統(tǒng)將拒絕他的提交,,因為他的修改基于代碼的1.1版,而目前的最新版本已經(jīng)是1.2了,。cvs提供了自動合并功能,,允許在兩個人修改的不是同一行代碼的前提下,自動合并本地修改和最新的代碼,,當然,,如果趕上兩個人同時修改同一行代碼的情況,cvs也會非常“聰明”地把兩個“英雄所見略同”的地方合并,。

    但如果兩個人恰好都修改了同一行代碼,,而且改的不一樣怎么辦?cvs會告訴后一個提交的開發(fā)者發(fā)生了這樣的情況,,并且要求他解決問題,。代碼中存在的差異將以<<<和>>>標記出來,以方便進行修改,。

    簡單說來,,當發(fā)生沖突時,我們通常約定由后一個提交者解決沖突——當然,,他可以選擇忽略這些沖突,,但這些操作都會被記錄,更何況,,統(tǒng)計顯示,,同時將一行代碼修改為兩種不同的樣子這樣的情況在實際開發(fā)中很少出現(xiàn)。于是,,修改流程繼續(xù),,如下圖:

    圖3. 開發(fā)者A解決沖突,并提交

    極端情況下,,可能出現(xiàn)多個開發(fā)者同時修改同一個文件的問題,。這一問題基本上可以按照上述的方法解決。當然,,為了避免發(fā)生這樣的情形,,在設(shè)計的時候就應(yīng)該讓每個人工作的代碼盡可能地不重疊。

    下面是非?;镜腸vs update/commit操作規(guī)范:


    簡單的cvs操作約定

    • 修改文件之前首先update,。這意味著修改時的版本盡可能新,一旦發(fā)生沖突,,解決它的工作量會比較小,。
    • 及時commit。本地代碼與代碼庫中的代碼差異越小,別人合并的難度也就越小(他們有比較大的概率能夠拿到新的版本)
    • 將不同的功能單元修改分開commit,。一方面,,這樣做能夠盡早地commit,減少別人合并的難度,;另一方面,,由于cvs提供了回退到先前版本的能力,一旦由于某項功能修改造成問題,,也很容易將那次修改的內(nèi)容,,而不是整個修改回退到正常的代碼。
    • 同一功能涉及的所有代碼一次commit,。不希望將涉及同一功能修改的代碼分開commit,,因為這會給日后的追蹤帶來麻煩。
    • 先調(diào)試后提交,。這將減少別人不會因為同步了中間結(jié)果引發(fā)問題,,甚至發(fā)生提交沖突的可能。
    • 寫清commit log(提交日志),。cvs中允許保存commit log,,在這里可以寫為什么進行代碼的修改,以及進行了什么樣的修改,,清楚的commit log能夠幫助其他開發(fā)者在不仔細閱讀代碼的情況下了解修改的內(nèi)容,,從而極大地提高開發(fā)效率;另一方面,,這些日志對于開發(fā)者自己,,以及整個開發(fā)團隊,都是非常寶貴的財富,。

    同步代碼(update)和提交代碼(commit)占到了cvs日常操作的80%以上,。從上面的介紹我們可以看出,僅僅依靠這兩項非常簡單的功能,,cvs就能極大地改善開發(fā)流程,,并提高軟件工程的可控性。簡單地說:

    • 全體開發(fā)者使用同一個中央代碼庫,,從而消除了由于來回復(fù)制文件導(dǎo)致的不一致,。
    • 發(fā)生沖突時,后提交的開發(fā)者必須解決它,。這名開發(fā)者能夠知道是誰引入了沖突,,他可以自己解決沖突,也可以與引入沖突的開發(fā)者商量如何解決沖突,。
    • 測試可以貫穿編碼過程的始終,,任何時候引入的新問題都能夠被及時追蹤,、快速定位,從而更有效地解決,。
    • 由于存在中央代碼庫,,代碼審核人員和每日構(gòu)建人員能夠及時地了解代碼是否存在問題,并幫助項目經(jīng)理保證開發(fā)進度,。
    • 有助于幫助開發(fā)人員養(yǎng)成嚴謹?shù)墓ぷ髁晳T——規(guī)則要求他們將盡可能地提交正確的代碼,并且每個修改必須寫commit log進行說明,。
    • 有助于建立更公平的工作質(zhì)量評估機制,。 cvs能夠記錄每個人完成的實際工作量,包括他們因為修正問題等等所作的勞動,,以及他們完成代碼的質(zhì)量情況,。這樣,管理者能夠為優(yōu)秀的開發(fā)人員提供更好的工作機會,、報酬,,等等,這對于鼓舞整個團隊的士氣,、提高開發(fā)人員的工作積極性都是非常有益的,。
    • 促進開發(fā)人員之間的交流。盡管cvs本身無法代替交流,,但commit log,,以及cvs系統(tǒng)獲取任意版本之間差異的能力,能夠幫助開發(fā)人員了解對方的想法,,并促進他們共同提高,。
    • 降低程序開發(fā)人員的門檻。由于提供了許多非常方便的協(xié)同開發(fā)手段,, 使用cvs能夠減少協(xié)同開發(fā)所需要的磨合期,,同時,不同層次的開發(fā)者之間由于能夠進行經(jīng)常性的溝通,,從而把編碼過程從技能型工作向熟練性工作又推進了一步,。這意味著高層次的開發(fā)人員能夠去進行更能發(fā)揮他們特長的工作,而新手則可以很快地融入到日常的開發(fā)活動中來,,從而提高勞動生產(chǎn)率,,降低開發(fā)成本。

    編碼過程中的溝通紐帶——commit mail

    cvs是一項開放性很強的工具,,它可以被非常容易地訂制,。一般來說,cvs服務(wù)器會架設(shè)在一臺Unix主機上(我們推薦使用FreeBSD),,通過使用腳本語言(例如,,Perl),,cvs能夠完成一些額外的功能。

    commit mail是commit log在郵件系統(tǒng)上的延伸,。下面是一封典型的commit mail,,它來自FreeBSD開發(fā)團隊:

    phk 2003/10/21 23:32:20 PDT

      FreeBSD src repository

      Modified files:
        sys/geom geom_io.c
      Log:
        Forgotten commit: If a provider has zero sectorsize, it is an
        indication of lack of media.

        Tripped up: peter

      Revision Changes Path
      1.50     +3 -6   src/sys/geom/geom_io.c

    我們看到,上面的這封commit mail中提到了開發(fā)者(phk),、提交時間(太平洋時間2003年10月21日23:32:20),、涉及的代碼庫名字(FreeBSD src repository)、修改過的文件(sys/geom的geom_io.c)以及commit log,。最后,,commit log還提到了提交后文件的最新版本(1.50),修改規(guī)模(+3 -6)以及代碼的實際路徑,。

    實現(xiàn)上面的功能并不復(fù)雜,,實際上,您只需要下載一套經(jīng)過定制的FreeBSD cvs代碼庫(壓縮包不超過40KB),,并作少量的調(diào)整,,就能夠直接使用這些功能(我們將在不久以后發(fā)布這些內(nèi)容)。進行這些訂制甚至不需要基本的Perl和C/C++常識就能夠完成——當然,,我想這樣的常識對于軟件開發(fā)人員來說,,并不算是很高的要求。

    commit mail可以通過郵件列表發(fā)給全體開發(fā)者,。許多大的軟件公司,,以及開放源代碼團體,都采用這樣的方式來協(xié)調(diào)開發(fā)活動,。

    日常測試——堅持每日構(gòu)建

    傳統(tǒng)的軟件工程中,,測試發(fā)生在連調(diào)之后。這么做的理論依據(jù)是,,測試依賴于一份一致的,、至少能夠正常編譯并啟動的代碼。而這個條件在連調(diào)之前是無法滿足的,。

    然而在有了版本控制系統(tǒng)(如,, cvs)之后,連調(diào)變成了開發(fā)中的日常行為,。代碼幾乎在每一時刻都處于高度的一致狀態(tài),,甚至在許多時候,代碼會處于可用狀態(tài),,從而為測試創(chuàng)造非常有利的條件,。

    許多大型開發(fā)團隊會使用一臺甚至多臺被稱作TinderBox的機器來完成每日構(gòu)建和測試。簡單的每日構(gòu)建流程如下:

    • 測試工程師,,或代碼復(fù)審員從代碼庫中提取一份代碼的快照
    • 相關(guān)人員在TinderBox上進行編譯
    • 編譯的任何錯誤被追蹤,,測試工程師或代碼復(fù)審員將回退代碼到上一次能夠成功編譯的點,,并與此后進行代碼提交的其他開發(fā)者進行聯(lián)系,解決問題
    • 測試工程師對于代碼進行測試

    其中,,第一,、二步是可以通過腳本定時、自動完成的,,不需要人工干預(yù),。第三步中的編譯錯誤在軟件開發(fā)中偶爾會發(fā)生(這可能來自于沖突合并時引發(fā)的問題,但由于開發(fā)人員的本地測試,,這種文體不會是經(jīng)常性的),,習慣上,這些錯誤會由代碼復(fù)審員去追蹤和處理,,并交給相關(guān)的開發(fā)人員解決。

    測試工程師可以將編譯好的版本交付給一個測試組,,甚至用戶去進行測試,。測試工程師可能隨時發(fā)布軟件的“快照”版本。

    實際上在許多大公司中,,每日構(gòu)建是非常“家常便飯”的事情,。我們看到的Internet Explorer版本,如6.0.2600或者類似6.0 Build 2600中的2600的意思就是這份代碼之前已經(jīng)經(jīng)歷了2600次每日構(gòu)建操作(當然,,中間肯定進行過不少修改,,而且,也不排除這個2600是故意湊整得到的,,但總之,,他們進行了相當多的日常構(gòu)建工作)。

    在軟件開發(fā)的后期,,由于發(fā)布的迫在眉睫,,每日構(gòu)建很可能會演化為持續(xù)構(gòu)建,即,,每次commit觸發(fā)一次構(gòu)建操作,。所有問題立即得到反饋。

    為了支持每日構(gòu)建或持續(xù)構(gòu)建,,比較理想的方法是采用Makefile完成構(gòu)建操作,。對于Unix系統(tǒng),make工具通常是pmake(BSD Make)或gmake(GNU Make),;對于Visual C++,,則是nmake。大的開發(fā)團體通常使用一組腳本來完成所有的make操作,,而對于中小型項目,,手工地使用類似VC++這樣的IDE本身的構(gòu)建功能也是可以接受的,。

    基本的每日構(gòu)建規(guī)范如下:


    基本的每日構(gòu)建和測試注意事項

    • 避免在存在開發(fā)人員大規(guī)模地進行commit時提取快照。此時提取的中間結(jié)果很可能有問題,,并導(dǎo)致每日構(gòu)建從頭做起,。通常,測試工程師和代碼復(fù)審員在多數(shù)開發(fā)人員下班的時候開始每日構(gòu)建,,因此,,每日構(gòu)建有時也被稱作每晚構(gòu)建(Nightly Build)。
    • 標記(tag)每日構(gòu)建中能夠正確編譯的版本,。這將減少第二天每日構(gòu)建中的麻煩,。
    • 及時通知造成問題的開發(fā)人員,即,,所涉及代碼的提交者,。某些公司甚至要求員工開著手機和尋呼機,以保證工期,。

    作為commit mail的有效補充,,許多項目開發(fā)組會建立郵件列表來傳遞一些相關(guān)的信息。測試日報通常會發(fā)給整個開發(fā)團隊的參加人員,,此外,,保留一個出現(xiàn)過的問題記錄,對于測試環(huán)節(jié)也會有相當大的好處——這些問題在隨后被反復(fù)測試,,以保證最終的RELEASE不出現(xiàn)這些問題,。

    每日構(gòu)建并不是可有可無的工作,作為日常測試的重要手段,,每日構(gòu)建能夠有效地幫助管理者了解工程進度,,幫助開發(fā)者盡早發(fā)現(xiàn)問題,同時,,也會促進開發(fā)組中的交流,。

    有效的版本控制——版本標記、代碼分支

    三個文件的“最新版本”分別是1.5, 1.3, 1.4,,但最新版本不一定是我們需要的,。在這種情況下,版本控制系統(tǒng)提供了一個非常重要的機制——版本標記,。例如,,我們目前已經(jīng)確認三個文件的1.4, 1.3, 1.4組合在一起能夠正常運行,于是我們在三個文件的這些版本上標注標記TAG_1,,如下圖:

    圖4. TAG_1標記被打到三個文件的不同版本上

    需要說明的是,,標記是可以被移動的。這意味著一旦發(fā)現(xiàn)標記打錯了,,可以把標記移動到別的位置,。但在實踐中,,標記往往同另一個非常重要的版本控制機制——代碼分支一起使用。在詳細討論標記(tag)的重要意義之前,,我們先來看看代碼分支時什么:

    圖5. 比較復(fù)雜的情形,,一個正在開
    發(fā)的項目中的某個文件,已經(jīng)完成了
    2.0和2.1的發(fā)布; 其中,,BP是指劃分
    分支的切分點(Branchpoint)

    所謂代碼分支是版本控制中的一個非常關(guān)鍵的概念,。當開發(fā)到某個階段的時候,可以交付一個版本,,而主要的開發(fā)者則把精力投入到最新版本的開發(fā)中,。第一個交付分支(2.0)中的一些問題,以及引入的新功能隨后在RELENG_2分支中被修正,,公司決定發(fā)布2.1版本,;此后,2.x中的問題繼續(xù)在RELENG_2中被修正,,而一些安全更新,,則被合并到2.1-RELEASE中(RELENG_2_1)。

    圖5展示的是一個文件上的版本分支,。實際的軟件工程項目的源代碼會由大量文件組成,盡管在本質(zhì)上分支是針對每一個文件說的,,但在被標注了同一分支名稱的文件,,就像版本標記一樣,能夠表達一組特定版本文件的集合,。

    cvs的版本分支功能有一個很大的缺陷,,即,大量文件的切分點(Branchpoint, 即某一個分支最初的版本號)在cvs中很難被指定(cvs支持按某一分支,、某一特定時間、某一特定版本來提取文件,,但通常不同的文件的版本號并不統(tǒng)一,,特別是在大型項目中,肯定有某些文件因為被提交的次數(shù)很多,,而版本號很“高”的情況),。為了消除這個缺陷,在實踐上,,我們采用版本標記與分支結(jié)合的方法,,即,在劃分新的分支之后,,在這一分支的這些文件的版本上增加一個版本標記,。

    例如:對于軟件的2.0版,,在劃分時,將切分出RELENG_2(2.x),,RELENG_2_0(2.0)兩個分支,,而這時的文件的版本,同時被打上一個RELENG_2_0_0_BP的標記,。這樣一來,,在以后比較版本時,我們可以使用RELENG_2_0_0_BP來指定這個版本,。當不同的分支又增加了許多修改之后,,這個標記將極大地減輕代碼復(fù)審員的工作量。

    注意,,代碼分支并不僅限于版本上的用法,。事實上,基于同一代碼基礎(chǔ)的多個不同的軟件也可以采用代碼分支的方法進行開發(fā),。而最終,,這些代碼還可以合并為一個。

    您可能已經(jīng)注意到最左邊的一組版本序列:1.1, 1.2, 1.3, 1.4, 1.5. 1.6,。在cvs中,,這一序列被稱為“主分支(MAIN Branch)”。盡管并非必須,,但習慣上,,主分支通常是活躍的開發(fā)分支。在這個分支中,,人們不斷地引入最新的特性,,當然,不可避免地,,這也可能引發(fā)一些問題,,而這些引入主分支的問題在隨后將被追蹤、修訂,。經(jīng)過一段時間之后,,被“沉淀”下來的代碼可以進入另一個叫做“穩(wěn)定分支”的代碼系。

    這樣的開發(fā)模式通常被稱作“多頭并進”模式,,這樣的模式在許多開放源代碼的軟件開發(fā)中非常常見,,例如,Linux的單,、雙號版本,、FreeBSD的-STABLE和-CURRENT[2],等等。在一般的商業(yè)軟件開發(fā)中,,這種模式也相當常見,,特別是在大公司的開發(fā)中。擁有多頭并進這一能力對于大型軟件的開發(fā)尤為重要,,因為大型軟件很可能包含相當多的模塊,,通過版本控制,問題能夠很容易地被整個開發(fā)團隊追蹤,。

    多頭并進的開發(fā)環(huán)境中,,開發(fā)人員可以在粗略熟悉了某個分支的代碼體系的情況下參與開發(fā)或維護,這意味著,,即使某個代碼分支的維護人員突然離去,,其他人也不用擔心通盤閱讀不同分支的代碼可能造成的理解困難,換言之,,對于新的維護人員的要求被降低,,從而,軟件的開發(fā)和維護過程能夠更為有序地進行,。

    據(jù)我所知,,F(xiàn)reeBSD的軟件開發(fā)過程極大地得益于多頭并進的開發(fā)模式。下面簡單地介紹一下FreeBSD所采用的軟件開發(fā)模式:


    案例:FreeBSD開發(fā)模式中對于多頭并進的應(yīng)用

    FreeBSD包括了兩個主要的開發(fā)分支:4-STABLE和5-CURRENT,,以及若干安全分支,。其中,4-STABLE(RELENG_4分支)代表的是FreeBSD 4.x系列的開發(fā),,其關(guān)注的焦點是系統(tǒng)的穩(wěn)定性和性能,;5-CURRENT(HEAD分支)代表的是FreeBSD 5.x系列的開發(fā),它關(guān)注的焦點是盡可能多地引入最新的操作系統(tǒng)特性,,全新的設(shè)計思想,等等,。除此之外,,還有一些被稱作安全分支的分支,它們分別代表FreeBSD 2-STABLE, 3-STABLE, 4.6-RELEASE, 4.7-RELEASE, 4.8-RELEASE以及即將推出的4.9-RELEASE等等,,但這些分支完全不引入任何新的特性,,只有安全更新能夠被加入到這些分支中。

    FreeBSD的“安全分支”是一個非常重要的概念,,在FreeBSD的開發(fā)中,,這些分支基本上只由一個包括了少量開發(fā)者(目前只有兩人)的,被稱為“FreeBSD安全官”的團隊維護,。對于很多用戶來說,,他們并不在乎操作系統(tǒng)是否擁有新的特性——他們不愿意嘗試新版本的軟件,因為現(xiàn)有的系統(tǒng)工作的非常好,。這些用戶使用“安全分支”的FreeBSD操作系統(tǒng),,因為他能夠提供必要的安全更新,,而操作系統(tǒng)特性并不會因此發(fā)生變化(無論這種變化是否能夠改進性能,或提供一些眩目的功能,,甚至支持新的硬件,,因為用戶的系統(tǒng)已經(jīng)放在那里了)。

    CURRENT分支走的是另外一個極端,。所有的新特性,,一旦被特定的工作人員(committer)測試通過(大的變化需要核心團隊,即core team的批準,,但這種情況并不是很多),,就允許被引入CURRENT分支。盡管CURRENT分支在絕大多數(shù)時間都能夠被正確地編譯,,但引入新特性有時會不可避免地帶來一些問題,,例如硬件適應(yīng)性問題。

    在這兩個極端之間,,有一條中間路線,,即STABLE分支。在CURRENT分支中提交的代碼通常會被指定一個MFC(Merge from -CURRENT)時間,,在這個時間之后,,如果沒有人提交關(guān)于代碼的問題,則這些代碼會被引入STABLE分支,。

    這樣,,STABLE分支的代碼幾乎都是經(jīng)過相當長時間測試的代碼,對于大多數(shù)用戶來說,,STABLE分支是一個很好的選擇,。

    一般來說,F(xiàn)reeBSD中的代碼會經(jīng)歷下面的歷程:

    • 代碼被引入CURRENT分支
    • 相關(guān)開發(fā)者獲得來自用戶的反饋; 在確認基本沒有問題的情況下,,代碼被引入STABLE分支
    • 大多數(shù)最終用戶使用STABLE分支的代碼來支持他們的計算機

    我們可以看到,,上面的開發(fā)模式同時照顧到了開發(fā)者和用戶群體的利益。一方面,,活躍的開發(fā)不會因為影響到了大量的普通用戶而遭到指責,;另一方面,在開發(fā)分支(CURRENT)的代碼經(jīng)過一段時間被引入STABLE,,最終用戶能夠得到那些新的操作系統(tǒng)功能,。

    事實上,上述開發(fā)模式已經(jīng)被證明是相當成功的,。由于開發(fā)過程中每一天都有相當多的人對新的CURRENT和STABLE分支的代碼進行測試,,因此,在最近的幾年中,F(xiàn)reeBSD的開發(fā)一直呈現(xiàn)著良好的態(tài)勢,。

    交付工程(Release Engineering)基礎(chǔ)——特性凍結(jié)和代碼凍結(jié)

    許多參與過大型項目開發(fā)的讀者可能都經(jīng)歷,,至少是聽說過特性凍結(jié)和代碼凍結(jié)這樣一個概念。所謂“特性凍結(jié)”實際上是一個開發(fā)者之間的約定,,在這個階段中,,不再允許添加新的功能。

    特性凍結(jié)(Feature Freeze)通常在一個開發(fā)分支(Development Branch)躍變?yōu)榻桓斗种?Release Branch)的時候開始,。之所以需要特性凍結(jié),,是因為增加新的特性很有可能引入新的問題,而這將給代碼復(fù)審帶來沉重的負擔,,甚至導(dǎo)致一次不成功的最后交付,。

    當然,對于那些已經(jīng)明確地定義了特性表的小型軟件工程項目(例如,,傳統(tǒng)的瀑布開發(fā)模型)來說,,特性凍結(jié)沒有什么意義,因為在這些工程中,,詳細設(shè)計完全是在編寫代碼之前進行的,,這意味著,代碼將要寫成什么樣子已經(jīng)在詳細設(shè)計中明確地定義,。但在實際的項目中,,詳細設(shè)計往往會包括兩類不同的類型要求——一部分是“必須實現(xiàn)的特性(Must have feature)”,另一部份則是“希望實現(xiàn)的特性(Desired Feature)”,。在交付之前,,所有“希望實現(xiàn)的特性”都會在特性凍結(jié)時被明確成“實現(xiàn)特性”和“不實現(xiàn)特性”。

    我們注意到,,這種情況下,,某些特性被延遲到接近交付的時候才被明確成“必須實現(xiàn)”,而另一些“希望實現(xiàn)的功能”則被作為“不實現(xiàn)”,,從而轉(zhuǎn)化為我們先前熟悉的樣子,,即詳細設(shè)計文檔中明確地定義了軟件中的所有特性。

    這樣做的結(jié)果是軟件工程項目具有更大的靈活性,。由客戶需求產(chǎn)生的功能設(shè)計,,很顯然地,,應(yīng)該列為“必須實現(xiàn)的特性”,,而那些開發(fā)團隊提出的能夠提高軟件整體可擴展性、可伸縮性或其他性能的特性,,則應(yīng)列為“希望實現(xiàn)的特性”,。在特性凍結(jié)之后,整個開發(fā)團隊將專注于那些“實現(xiàn)特性”(盡管這些特性可能還沒有被正式的實現(xiàn))更加穩(wěn)定,從而將生產(chǎn)出更高質(zhì)量的軟件,。

    根據(jù)我個人的經(jīng)驗,,特性凍結(jié)應(yīng)該發(fā)生在預(yù)期編碼時間已經(jīng)用去大約2/3的時候。這時,,項目經(jīng)理應(yīng)該組織開發(fā)人員舉行一次會議討論特性凍結(jié),,而在特性凍結(jié)之后,在軟件正式交付之前,,任何開發(fā)人員都不應(yīng)該再去考慮那些被列為“不實現(xiàn)特性”的功能,。

    代碼凍結(jié)是一個與特性凍結(jié)類似的概念,在這個階段,,只允許對被凍結(jié)代碼分支中的錯誤進行修正,,而不允許任何其他的、涉及功能的修改,。實踐上,,這個過程中,只有交付工程師(通常是一個或多個對于整個系統(tǒng)架構(gòu)非常了解的,、有豐富開發(fā)經(jīng)驗的代碼復(fù)審員)被授予審查和批準代碼提交的權(quán)力,,任何代碼修改,只要沒有經(jīng)過交付工程師的批準,,就不能被提交到代碼庫中,。

    代碼凍結(jié)的時間一般不需要太長。對于中等規(guī)模的項目,,這一過程通常會持續(xù)一至兩周,,對于大型項目,這一過程則有可能持續(xù)一個月甚至更長的時間,。在這個階段,,交付工程師主要負責代碼復(fù)審,而測試工程師則有責任及時反饋集中的測試中暴露出的問題,,并與相關(guān)的開發(fā)人員聯(lián)系,、解決這些問題。

    技術(shù)上,,代碼凍結(jié)可以通過修改cvs中的配置來實現(xiàn),。不過,更好的辦法是通過制度來保證代碼凍結(jié),。

    交付工程——編碼階段的總結(jié)

    交付工程的好壞在某種意義上,,是直接關(guān)系到用戶利益的部分。前面已經(jīng)說了相當多的關(guān)于軟件開發(fā)過程中通過版本控制技術(shù)來提高開發(fā)效率的技巧和方法,,這里我將繼續(xù)說一說交付工程,。

    前面提到了每日構(gòu)建中在代碼上適當?shù)卮蛏习姹緲擞?,以及在劃分版本分支時在切分點上增加版本標記,這些對于交付工程都具有非常重要的意義,。交付工程,,在軟件工程項目中是一個融合了代碼復(fù)審和集中測試的重要階段。


    交付工程的一般程序

    • 在項目進行到某個特定的階段,,交付工程師同其他主要的項目管理者商議決定宣布代碼凍結(jié)和交付工程開始,。
    • 交付工程師對代碼進行集中的復(fù)審,而測試工程師則組織進行大規(guī)模的集中測試,。
    • 交付工程過程中,,交付工程師每隔一段時間發(fā)布一個“交付候選版本(Release Candidate)”,測試工程師跟隨安裝并測試這些交付候選版本,。
    • 此間,,測試工程師隨時向交付工程師反饋問題,交付工程師將問題分類,、整理,,并約見相應(yīng)的開發(fā)人員,予以解決,。
    • 最終,,某個“交付候選版本”被最終指定為交付版本(Release)。代碼凍結(jié)結(jié)束,,軟件被交付給客戶,。

    一些讀者可能已經(jīng)注意到,交付工程的絕大多數(shù)任務(wù)事實上已經(jīng)被融入了我前面所描述的開發(fā)過程——在編碼階段的整個過程中,,代碼復(fù)審,、問題反饋和測試一直是持續(xù)地進行的,只是,,在“交付工程”階段,,代碼復(fù)審和測試被提升到了一個更為核心的地位,在這一階段,,開發(fā)的重要任務(wù)是查錯和排錯,,而不再是將軟件的功能推向一個嶄新的水平。

    總結(jié)——基于版本控制,、每日構(gòu)建的編碼過程

    前面我們已經(jīng)介紹了通過引入版本控制系統(tǒng)改善軟件工程中編碼和測試階段過程的一些方法,。這些方法來自于我本人所參與的,以及通過一些其他途徑了解到的實際項目的開發(fā)經(jīng)驗,。文中介紹的內(nèi)容以cvs (Concurrent Version System)為主,,這是因為cvs比較容易得到(它本身是開放源代碼軟件),并且,,比較成熟,。另外,由于關(guān)于cvs本身的細節(jié)并沒有涉及很深,,因此,,讀者也很容易將這些經(jīng)驗套用在其他版本控制系統(tǒng),如Bit Keeper, Perforce, Clear Case等等之上,。

    引入版本控制,、每日構(gòu)建之后,項目管理人員和開發(fā)者可以明顯地感受到以下改善:

    • 問題能夠盡早暴露,,并被解決,。測試過程被滲透到開發(fā)過程中,有利于及早發(fā)現(xiàn)問題,。日常的每日構(gòu)建和測試意味著更多的測試者可以盡早地參加到測試工作中,,并與開發(fā)團隊并肩作戰(zhàn),及時地為他們提供第一手的資料,;而最終的交付工程中進行的測試,,只是驗證軟件的質(zhì)量確實達到了設(shè)計要求,而不再肩負發(fā)現(xiàn)問題的重大責任,,這意味著很難出現(xiàn)最后階段發(fā)現(xiàn)嚴重問題而導(dǎo)致工期大大加長的尷尬局面,。
    • 每個人做了多少工作在版本控制系統(tǒng)中能夠非常有效地體現(xiàn),這對于更客觀地評價一位開發(fā)者的能力,,明確獎懲和提高員工積極性,,都有非常積極的意義。
    • 管理者能夠隨時觀察工程的進度情況,,并且,,每日構(gòu)建的到的版本也可以交付給客戶,從而改善軟件開發(fā)團隊同客戶之間的交流,。
    • 版本控制系統(tǒng)記錄的軟件工程的進展,,對于今后的開發(fā)將是一筆寶貴的財富。

    最后,,讓我們用圖片的形式,,重新描述一下上面的那些過程:

    圖6. 日常開發(fā)過程

    圖7. 交付工程

    這樣,我們已經(jīng)粗淺地討論了關(guān)于并行版本控制技術(shù)如何改變軟件開發(fā)過程的一些大致的方法,,以及其中的一些先進思想,。在文中我盡可能地回避了類似cvs系統(tǒng)的操作具體細節(jié),并且,,避開了一些cvs特有的功能,。基本上,,本文中提供的方法,,特別是其中的一些思想,,能夠適應(yīng)任何一種版本控制系統(tǒng),因此,,這些方法具有相當大的普遍意義,。

    參考文獻

    [1] CVS - 并行版本系統(tǒng) http://www.
    [2] FreeBSD 4.4交付工程, Murray Stokely
    [3] CVS使用手冊- CVS WinCVS CVSWeb CVSTrac,車東
    [4] 4.3BSD交付工程, Marshall Kirk McKusick, Michael J. Karels, and Keith Bostic

    作者簡介

    李鑫,,北京工業(yè)大學計算機學院2000級學生,,目前擔任計算機學院學生科協(xié)主席、放飛技術(shù)網(wǎng)技術(shù)總監(jiān),。您可以通過電子郵件 ( delphij@ 與他聯(lián)系 ),。

    版權(quán)聲明

    本文版權(quán)歸原作者和放飛技術(shù)網(wǎng)共同所有,轉(zhuǎn)載本文必須同我們聯(lián)系并獲得同意(書面或PGP簽署的許可),。

      本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報。
      轉(zhuǎn)藏 分享 獻花(0

      0條評論

      發(fā)表

      請遵守用戶 評論公約

      類似文章 更多