小軟件項目開發的管理 一個企業的管理,大公司有大公司的方式,小公司也有小公司的方式,如果把別人 的經驗生搬硬套到自己身上,可能會適得其反。同樣,管理一個軟件項目也一樣,大項 目和小項目的方式不完全一樣。但從另一個角度來看,項目的大與小並沒有本質的區別 ,很多方法是共通的。本文的目的是從作者的經驗來談談小項目開發的管理。 一、小項目的特點 大家知道,“軟件危機”的出現起源於一些大型項目的不斷延遲甚至失敗。小項目 相比之下,具有以下特點: 1.項目功能相對較少 2.開發人員較少 3.開發周期較短 另外,在現實中,有很多小項目是由一些中小公司進行開發的,這些公司往往人員 流動性較大,這也是不容忽視的一個現實. 二、小項目開發中常犯的錯誤 小項目看起來比較簡單,比較容易成功,因而人們往往忽視了小項目的管理,其實 這是一種誤解,從本人的經驗看來,小項目開發中容易犯以下的一些錯誤: 1、開發之前沒有認真地進行項目可行性和工作量的估計。 往往由於項目較小,便很草率地制定一個開發日程表,沒有認真地估計項目難度, 結果實際完成時間與估計完成時間往往有較大差別。 2、沒有真正的設計過程 開發人員少,意味著不同人員的程序之間交互、接口相對少一些。開發周期短意味 著往往是同樣的幾個人從頭到尾負責一個項目。這兩者都讓人容易犯些錯誤。往往是幾 個人碰一下頭,討論一下最基本的數據結構、函數接口便分頭去做自己的工作了,沒有 一份較正式的文檔。 這種做法潛在的危險之一是有的人可能會對討論出的接口、結構理解有偏差(應該承 認人是會犯錯誤的)。一個誤解可能造成以後的返工。 另一個潛在的危險是由於討論時忽略了某些情況,等大家都按當時的分工完成屬於 自己的工作後,才發現各個模塊組合起來卻形不成一個完整的系統。其根源在於沒有一 個負責協調的人員不斷監控整個開發過程。 第三個潛在的危險是一旦有人中途退出開發隊伍,其他人加入時,新來的人難以理 解以前別人做好的代碼,索性自己從頭來。另外,沒有文檔的程序,日後維護和版本升 級都比較困難。 3.不經過單元測試而直接進入系統測試 造成這一現象的原因是每個模塊相對比較簡單,但是為了測試一個模塊需要建立一 些測試環境。例如,為了測試一個函數是否正確,應該用一些測試數據去調用該函數, 需要編寫一些測試數據。但很多開發人員嫌麻煩,覺得反正其他模塊也很快出來了,直 接用真正的數據來運行幾次就行了。 殊不知,一旦直接進入系統測試,發現運行結果不正確後需要一步步查找。由於模 塊間的調用關系,可能查了很久才發現是某個模塊的問題。這種方法一來效率比較低, 大量的時間用在了將一個錯誤定位在模塊上了。另外由於這種測試不完全,真正運行系 統,當調用某模塊時,可能大部分時候都是正常數據,極少出現邊界情況,可能某些邊 界情況容易被忽視,很久之後才被發現。但是如果對每個模塊進行單元測試時都進行一 下邊界測試,就會很容易消除一些隱患。真可謂欲速則不達也。 三.合理的開發流程 合理的開發模式,一句話形容就是“麻雀雖小,五髒俱全”,即使是小型項目的開 發,仍然應該遵循軟件開發的一般規律,必須的步驟不能省略。但是小項目有它自身的 一些特點,實行起來可以相對靈活些。 以下我從幾個方面描述一下我認為比較合理的模式. 1.需求獲取 在進入正式開發之前,必須先從用戶處獲取准確的需求。在這上面花費相當時間是 很必要的。 軟件項目可以大致分為專用軟件和通用軟件兩大類。 對於專用軟件,例如給某單位開發一套該單位專用的系統,一般用戶對於軟件要完 成哪些功能已經有了一個比較清楚的輪廓,而且往往在開發合同中已經大致地規定了。 但是,開發合同上規定的只是一個大概的框架,在進入開發之前必須與用戶進行比 較具體的交流和討論,了解清楚用戶心目中的產品究竟是什麼樣子。這個步驟如果沒有 好好做,往往到了開發工作的後期才發現開發人員的理解和用戶的要求有一些誤解,那 麼必然造成時間上的浪費。 對於通用軟件,在開發之前應該做一定的市場調查工作,一方面是從經濟效益考慮 ,調查產品的潛在市場有多大,另一方面是從技術的角度,必須了解清楚潛在用戶對軟 件的各種技術上的要求,例如,用戶現有硬件配置如何,軟件配置如何,使用什麼網絡 ,使用什麼數據庫等等,根據調查的統計結果決定即將開發的軟件的一些技術指標。 為了比較好地與用戶進行交流,使用一些工具是很有好處的。 為了討論用戶界面,可以用VB, Delphi等做一個原型,根據原型有針對性地與用戶 討論需求。(原型開發不僅僅可以用於准確獲取用戶的需求,開發出來的原型本身可以作 為下一步開發的基礎,增量式地完成開發) 為了討論軟件運行的流程,可以采用UML的Use Case圖。 2.需求分析 在了解用戶的需求之後,將需求用一種模型來表示,就是需求分析,目前比較流行 的分析方法是面向對象的方法,通過分析用戶需求,用類、類之間的各種關系來表示整 個系統。 這部分涉及到具體的方法,在此不詳細討論,但是原則上是提取類->類之間關系,可 能需要不斷修改而形成一份分析文檔。 我想強調幾個問題。 一是要分清問題域與系統責任。系統責任是指所要開發的軟件應該完成的功能,而 問題域是包含所有相關的部分。例如你要開發一個程控機計費程序,程控機已經是現成 ,輸出的數據格式也已經是固定的,你的程序僅僅需要從程控機中讀取相應的信息,那 麼,"程控機"在你的系統裡只是一個外部的東西,把它作為一個類也許就是不必要的, 僅僅需要一個類來完成讀數據的操作。又如,你需要在一個已經存在的數據庫上開發一 些應用,數據庫的格式已經固定,並且已經有一個後台程序在運行,你需要開發一個新 的前台程序,這時,服務器程序對你來說就是一個外部的東西。但是,象這種外部的內 容必須在分析文檔中有一些說明,作為系統的外在約束。 二是需求獲取與需求分析的關系。 用什麼方法來完成需求的獲取,在很大程度上影響了需求分析的做法。 例如當初采用Use Case來表示用戶需求,那麼從各種序列圖中選出相互交互的各個 實體,就是一個個類。 三是分析與設計過程的銜接。 分析過程的內容是用類的結構來表示目標系統,並不設計具體實現,如采用什麼編 程語言,在什麼操作系統平台上運行等等。這些具體實現是在設計階段來完成的。面向 對象方法的優點是分析、設計、編碼過程表示法統一,能比較好的銜接。但是,是把分 析和設計階段分開,采用瀑布式開發,還是采用其他方式,要看具體的情況。 對於需求潛在變化不大的項目,可以采用瀑布模型,有一個很明顯的設計階段,這 樣做的好處是有一份比較完整的分析文檔,這樣以後如果需要采用不同的編程語言、或 者采用其他的平台時,便可以以這份分析文檔作為開發的基礎。 對於需求變化頻繁的項目,可能采用少量分析->少量設計->少量編碼->測試的方式 更合適,而且隨時可能要返回到前面某個一階段去進行修改。但是這意味著可能沒有一 份完整的分析文檔。 現在很多CASE工具並不區分分析和設計的階段。但是,這並不意味著開發就可以對 分析和設計不加區分,CASE工具如同一支筆,如何用好還得還人。 3.設計過程 設計階段的工作包括: 對分析模型必要的修改。可能需要對某些類結構進行一些修改,這些修改的原因可 能是編程環境的要求,或者為了重用以前的某些工作。 定義界面部分、數據訪問(數據庫)部分。 由於目前很多編程語言都可以可視化地設計界面,所以界面部分工作往往留到了編 碼階段來完成。於是設計階段的工作量並不大。 4.編碼 進入編碼工作之後,可能會發現前面分析或設計階段的某些錯誤,這時應返回到前 面的階段進行必要的修改。 5.測試 如前所述,即使是小項目,也應該嚴格地進行測試。 四、人員的安排 比較小的項目,往往是幾個人來完成,這幾個人基本上從頭到尾參加開發。在這幾 個人中,有一位項目負責人,負責分析、設計和協調的工作。由於項目小,項目負責人 也要參加編程,那麼這人必須把時間合理運用, 經驗告訴我幾條原則: 1.協調幾個人的工作比自己完成一段編碼更重要. 由於協調上出了漏洞,可能導致很大的問題,所以項目負責人必須隨時監控各開發 人員的工作,包括內容是否與要求發生偏差,進度是否滯後等等。 只有在完成這些工作之後,項目負責人剩下的時間才能用於編程。 2.給每個開發人員明確的任務書. 不管是用面向對象或者其他方法開發,分析、設計模型只是從功能的角度來描述系 統。但是,具體開發時每個開發人員必須非常明確自己的任務,這些任務應該采用明確 的文檔來表示。 3.讓大家都大致熟悉設計模型. 讓每個開發人員都清楚自己所做的工作在整個系統中處於什麼地位,有時侯可能會 發現設計模型中的漏洞,避免了各人的代碼編寫完畢之後又要修改的後果。 Microsoft 的軟件開發--快照 //摘自《開發過程調試技術》(《Debugging the Development Process》 Steve Maguire著 岳晉生 等譯;電子工業出版社 ISBN 7-5053-3067-5)一書,講述了微軟管理軟件項目的經驗,是一本很有參考價值的書。 本書中的大多數例子來自我在Microsoft的經驗。對於Microsoft 公司裡如何在主管人員之間劃分責任進行一個簡短的描述以及一個典型項目如何進行的概貌可能會幫助讀者理解這些例子的背景. 一個Microsoft的項目一般至少有三種不同的主管人員直接為產品的開發而工作。 * 項目主管. 項目主管最終為代碼負責。他或她也負責開發和監督進度,使項目按預定計劃進行、培訓程序員、為上層管理進行程序檢查,等等。項目主管通常是小組中最有經驗的程序員 並且常寫代碼,但只是把這當作第二手的工作. * 技術主管. 技術主管是小組裡的程序員之一,他比其他任何人都更了解產品的代碼。技術主管負責產品的內容完整性,使所有的新功能都用腦中已有的代碼來設計。他或她通常也負責確保項目的的所有技術文檔是最新的: 文件格式文檔、內部設計文檔,等等。如同項目主管一樣,技術主管通常是小組中最有經驗的程序員之一. * 程序經理 程序經理負責協調同市場、文檔、測試和產品支持等關系產品的開發工作。簡短的說,程序經理的工作是監督產品--每件放在產品封裝盒中的東西--的完成,並且是以公司希望的質量標准完成。程序經理通常同產品支持小組一起工作協調產品的外部beta版的發布,並同最終用戶一起工作來看怎樣提高產品。程序經理通常自己也是程序員,但他們的編程工作限於使用產品的宏語言(如果有的話)來編寫“指南”(wizards)和其他有用的最終用戶宏。不是別人,正是程序經理負責產品應是什麼樣的“構想”. "程序經理"的名字可能讓人誤解,因為它暗示程序經理在職位上高於項目主管、測試主管、文檔主管和市場主管。實際上,程序經理是同其他主管位於同一層次的職位。程序經理的更適合的名字應該是“產品主管",因為程序經理負責確保產品的所有部分--不僅是代碼--按進度完成並且是按可以接受的質量完成。 在一個典型的項目中,程序經理(如果項目足夠大的話,則是經理)在前期同市場、開發和產品支持小組一起工作,提出產品的改進列表。在創建功能列表之後,程序經理撰寫產品說明書,它詳細描繪每項功能應該怎樣提供給用戶--例如,提供一個新對話框的繪制方法以及如何使用它,或是提供一個新宏函數的名字以及它的參數描繪。一旦產品說明書的草圖完成之後,將把它傳遞給該產品涉及的所有小組,進行徹底的檢查。一旦最終說明書確定下來,各小組就開始工作。 程序經理同時使用功能的實體模型來進行可用性研究,以確保所有這些新功能直觀上同每個人開始想的那樣易於使用。如果一項功能顯得難以使用,程序經理建議對說明書進行修改。程序經理也為產品盤的樣例文檔和我前面提到的最終擁護宏而工作。當功能完成時,他或她將逐項檢查一確保它滿足交付產品的所有質量標准--特別是,功能在低檔機上也有足夠的活力。 開發工作繼續向前,並最終到達一點,稱之為“可視冰點”(Visual freeze),是指所有會影響顯示的功能都完成了。一旦代碼到達可視冰點,用戶手冊將用程序運行時的屏幕畫面來寫成。結果是,從該點開始,開發人員要小心不要以任何方式影響顯示,從而是手冊中的屏幕畫面同程序運行時用戶看到的畫面保持一致。當然,程序員希望在所有代碼完成後在截取屏幕畫面,但是手冊需要很長的時間,在代碼完成之前必須送去印刷。在一些情形裡,為了讓所有功能及時達到可視冰點以便在產品發布時能准備好手冊,程序員僅部分地完成功能--例如,顯示一個無功能的對話框,只用於屏幕截取而不干別的事情。以後,程序員再返回來全部地完成它們。 一旦所有的功能完成之後--“代碼完成”階段--程序員將努力修正錯誤列表中的所有重大的錯誤,並做一些必要的功能上的改進。當代碼最後准備交付時,項目主管或技術主管生成“金主盤”. 程序經理將金主盤送去復制生產,並將軟件和手冊、注冊卡和其他東西一起裝盒.稍稍壓緊並包裝之後,產品就准備好可以出售給用戶了。我省掉了許多細節,但是這樣簡短的總體描述足以讓你理解本書中偶爾出現的可能過於Microsoft化的例子的背景。 我也該指出,e--mail是Microsoft的生命血液,所有內部事務是通過e--mail進行的。並且,至少是在開發周期中,你必須真正有充足的理由才能用電話打斷他人的工作。開發人員之間的大多數交流通過e--mail進行,以及在許多自發進行的大廳會議中進行。這種全體對打斷他人工作的敏感性很好地說明了Microsoft的政策:給每個人一個帶門的個人辦公室。如果你在工作並且不想被打攪,你只要關上門就行. 做起來比聽起來難 我最後擔心的是,本書可能讓人聽起來似乎應用了它提供的所有建議後,一夜之間,能轉變一個不完美的項目。你確實可以立即應用書中的許多技術和策略,可以很快取得效果;但是其他的--例如培訓技巧--要花上一段時間才能有效果。如果你的小組現在出了問題,則不能指望讀完本書一星期後就將項目扳轉過來。以我的經驗來說,扭轉一個遇到麻煩的項目要兩到六個月的時間,大多數的好轉發生在頭兩個月裡。然後,進一步的好轉來得很慢並且幅度不大。 後記--關於領導的一句話 偶爾我會冒出這種想法,就是作為項目負責人,你不可能也永遠不會成為小組的一部分,你總要高出一級,而對此你無能為力。在我自己的經歷中,卻並不如此。我曾經成為過許多小組的一員--既當負責人又做程序員--而且無一例外,那些凝成整體的小組總是這樣一些小組,其項目負責人只是小組的另一個成員,而他碰巧要做些非編程的事情,也從來沒有負責人要高人一等的感覺。 對於某些不了解美國橄榄球的人來說,四分衛相比於其它隊員來說是個較高級的位置。不管怎麼說,四分衛調配著每場比賽,四分衛是控制著球的焦點人物,在勝利後總是四分衛被別的隊員拋起來。 四分衛可能顯得比其它隊員地位要高一些,但我們要了解得更清楚一點。四分衛隊員是另一個隊員而已,只不過碰巧承擔某種獨特的任務。一個有效的項目負責人同樣如此。他或她應當明白,一個焦點隊員並不比其他成員地位要高。 項目負責人只是另外一名成員而已,與其他隊員一樣,都有著自己獨特的職責。 有成效的領導人明白每個小組成員在組裡起著不同的作用,有些組員負責項目的數據輸入部分,有些負責打印功能,還有的負責外部文件轉換器和用戶界面設計,負責人可能要象其他人一樣實現某部分功能,但除此之外,他還有職責設定項目的目標和優先級,通知測試和市場這樣的獨立的小組該項目的進展情況,創造出一個小組成員能有效工作的環境,並保證小組成員不斷學習新的技能,以這種方法增加對公司的價值。一個項目負責人可以做所有這些工作,而並不認為自己要高人一等。 如果項目負責人有了高人一等的態度,就會引發一整串有害的行為。這裡列出的是極端情況下會發生的一些事情。 * 項目負責人將失敗歸罪於小組,而將成功據為己有。 * 項目負責人不關心組裡的人員。他們只是些工人,誰又在乎他們每周工作80個小時呢?負責人只關心小組不能按期交貨會使他臉上無光。 * 項目負責人希望小組成員對他唯命是從,從不對他的權威性表示懷疑。"我說了這麼做,就這麼做"是其座右銘。 * 急於顯得自己在哪一方面都不比別人差,負責人會攻擊那些威脅到他的權威和在某方面比他更有能力或知識更豐富的小組成員。 * 因為他必須永遠正確,當他錯了時,他從不承認。 * 項目負責人讓每一個對開發過程提出改進意見的人閉上嘴巴,或是擾亂開發工作的順利進行。 * 項目負責人以為自己是必不可少的人物. 當然,並不是所有那些認為自己高人一籌的項目負責人都這麼專橫,但即使是在較緩和的情形下,這種高人一等的意識也會流露出來。究竟小組成員是在為項目負責人工作,還是與項目負責人一起工作?項目負責人的言語就反映出了他的態度。 一個項目負責人如果把自己看作是小組的一員,就會工作得更順利,因為他幾乎不用花時間讓那些組員擺正自己的位置--為什麼他要這樣呢?采取並不高人一等的態度,他就使自己不必要去對付那些對他權威的威脅。如果他在剛接手的小組裡發現了一位超級明星,他也不會提高警惕,去開始一場一山不容二虎的龍爭虎斗,而這種斗爭在那些認為自己高人一等的負責人中非常普遍。這樣一位負責人更有可能覺得幸運,可以為了項目的利益與那位超級明星攜手工作。 作為項目負責人你所采取的態度會影響你所做的每一件事情。如果你和某位組員關於性能復審意見不同,你會如何反應?你是會因為覺得自己必須正確而固執己見呢,還是會討論一下該問題,看看能否有一種更站得住腳的解釋?如果你和組員意見相左,你是否會修正一下復核報告,將兩種立場都寫進去,以便以後讀到這份復核報告的人能夠自己去作出評價? 再看一看列出來的那些堅持認為自己高人一等的項目負責人的那些典型行為吧。一個把自己看成只是小組裡的另一名成員的負責人會這麼做嗎?在一種認為自己要高人一等的負責人和那種更加尊重你的負責人之間,你更願意與那一種人共事呢?要成為你願意與之共事的那種負責人。 項目負責人要把自己看成小組中的一員,而不要以為自己高人一等。