| 關於《人月神話》一書,已經有了許多評論和討論。可能,作者本身的經曆——“被認為是‘IBM 360系統之父’,他擔任了360系統的專案經理,以及360作業系統項目設計階段的經理。”——已經是最好的評論。 許多朋友認為現在的軟體工程資料比較理論化,可操作性不高,往往只能瞭解一些理念。在面對具體項目的時候,還是有些迷茫。而在整個翻譯的過程中,Brooks的觀點以及治學態度經常令人歎為觀止。這裡,就自己的一些體會和實踐同大家探討。 “焦油坑(The Tar Pit)”一章中,對編程系統產品的觀點“編程系統產品(Programming Systems Product)。和以上的所有的情況都不同的是,它的成本高達九倍。然而,只有它才是真正有用的產品,是大多數系統開發的目標。”很有意義,至少在面對現在許多老闆們對管理的觀點“現實世界中的管理就是在更大程度上以人員的生命為代價,讓他們更努力、更長時間地工作。經理們總是不停地吹噓他們的人員的加班時數和能從這些人身上榨取更多時間的小把戲。”(《人件》,即將由清華大學出版社出版,譯者為UMLChina翻譯組方春旭、葉向群)面前聰明的工作。這種情況下,開發產品的品質一定會下降,甚至慘不忍睹,因為開發人員唯一能控制的是品質,當他們不得不犧牲品質,痛苦面對自己的工作,踐踏工作的樂趣時,可以想象項目成本會大量地增加,並且項目的發布往往伴隨著一大批程式員的倒下。 團隊組建 “人月神話(The Mythical Man-Month)”提出了這樣的論斷,(盲目地)“向進度落後的項目中增加人手,只會使進度更加落後。”這中間還涉及到如何組建你的Team Dev,或者面向一個軟體開發工作單位時,如何規劃開發計劃、劃分任務項、分配資源。緊接著,在“外科手術隊伍(The Surgical Team)”中,Brooks提出了用外科醫生+副手來組織團隊,保證設計思路的完整性。其中,還提到了採用“語言專家”來協助疑難問題的解決;安排工具維護人員,也就是現在意義上的系統管理員來保證系統開發、管理環境的有效運行;而其他人來解決一些檔案管理等工作。
在一個小型的C++項目操作中,對上述方法的實踐中
- 由PM和結構師一用一備來分析需求、進行架構設計,確保整個項目的概念完整性。分析設計的產出物達到架構示意代碼的層級,這部分架構代碼主要是協助團隊對項目開發的理解,不存在於正式的代碼中;
- 安排開發人員負責組態管理。這裡的組態管理不僅僅局限於文檔、軟體產物的管理,而是在使用架構驅動的反覆式開發法時,需要對架構和各個組件不斷地進行編譯、整合、檢查記錄Bug。這位開發人員往往是團隊中的主程式員(Chief Programmer),對各種開發方法、方法學有著一定的經驗;
- 安排人員對工具進行預研,如瞭解STL類庫等。該角色具體的人員在不同的階段會進行調整。因為,他/她需要對語言、類庫、開發技巧進行學習研究,往往會佔用大量的工作時間。在實際情況中,前期是有主程式員承擔;後期,由PM承擔;
這樣的安排的確能解決產品思路的一致性,在很大程度上提高生產力和產品品質。不過,它要求: 1. PM和結構師有非常良好的溝通,包括分析方法的風格、對開發的理解等,他們之間的不一致直接會導致項目的開發方向; 2. 對分析的結果,進行良好的貫徹。軟體行業具有年青、有朝氣的特點,同時也有些浮躁。有的開發人員好高騖遠,對代碼品質重視不夠,影響架構的穩定性。 這樣安排的風險在於“外科醫生”的工作負載可能過大,尤其在國內的公司中,他們往往同時兼任PM和系統分析的工作。同樣,相應的績效考核機制也不容易具備。 另外一個風險在於“一用一備”的安排,在“為什麼巴比倫塔會失敗?(Why Did the Tower of Babel Fail?)”的“大型編程項目的組織架構”中詳盡地論述。不過,在國內的開發環境下,似乎很難實行。比較折中的方案,是對某種類型的項目,包括業務類型、開發方法、語言類型,建立開發和管理指南,從而保證概念完整性。在後續所經曆的一系列Domino類型的項目開發中,進行了嘗試,相應在實踐中遇到的問題在於如何貫徹實施。 上述方法潛在的一個聲音是“軟體重用性”。提到重用性,可能大家腦海裡馬上想到的是對象、類庫等。不錯,物件導向的方法、商業組件(類)庫的確極大地提高了軟體重用性。但對於中小型企業,甚至於一個成熟的Team Dev,積累自己大粒度的架構是提高軟體生產力的一個重要措施。設計模式中一些模式,如Visitor、Observe本身就可以作為軟體架構來使用。以設計模式為基礎,根據開發類型積累特定業務領域的架構是完全可行的最佳實務。而Brooks一再強調“概念完整性(Concept Integrity)”,以及在“外科手術隊伍”中推薦由外科醫生來負責系統的開發,保證了產生的系統是少數人思維的結果,它們往往簡捷、純粹,沒有眾多人的影響,經過了項目的洗禮之後,往往能成為重用的架構。相反,在分析設計階段,安排許多開發人員來共同開發,儘管同樣完成了項目,但會相應導致“畫蛇添足(The Second-System Effect)”特徵——“它極富有創造性,極端複雜,非常高效。但不知為什麼,同時也感覺到粗糙、浪費、不優雅,以及讓人覺得必定存在某種更好的方法”,而重用的架構往往是捕捉到了問題的根本,用簡單優美的方案,解決80%的問題。 貫徹實施 Brooks在“貴族專制、民主政治和系統設計(Aristocracy, Democracy, and System Design)”一章中,一針見血地指出了成功軟體具有高度的概念一致性。“結構師難道不是新貴?……至於貴族專制統治的問題,必須回答 “是”或者“否”。就必須只能存在少數的結構師而言,答案是肯定的……”,《人月》中的體繫結構更加類似於現在的需求概念,而非現在所意義的體繫結構。不過,在具體的實踐中,需求和體繫結構依然應該由少數的人來承擔。這樣的觀點可能會引起爭議,但就個人觀點而言,軟體行業實際上是“精英行業”。高素質、具有豐富經驗的需求分析人員、結構師往往是軟體企業的核心骨幹人員,相應的一般編程人員相對的流動性會大一些。 從個人發展的角度,安安靜靜地作為一個螺絲釘彷彿不是這個時代精神。這個問題同企業與人之間的關係一樣,很難一言以蔽之。就具體的項目操作,理想情況是程式員較少地參加前期分析工作,由有經驗的同仁來負責,給出具有架構代碼程度的需求和架構產物。 在較早的項目中,有的一般編程人員不安於編碼實現,過早接觸於一些PM性質工作,以及項目壓力等其他因素,造成了代碼品質不高,使得架構的重用程度降低。而在另外公司的一個項目中,由於企業的文化,同事們嚴格按照分工進行開發,提高了品質。後者看似少了機會,但從長遠的角度看,大家對設計的瞭解更加透徹,對流程的理解更加深刻,為以後的發展打下了基礎。 同樣在這一章節中,Brooks提出了“在等待時,實現人員應該做什嗎?”的問題。他認為“首先,必須設定良好定義的時間和空間目標,……同時,在物理實現的層級,也有很多可以著手的工作。”實際項目中,早期的投入往往人員較少,一般15人月左右的項目,初期就2~3人,這其中包括了需求分析、設計人員,以及主程式員。主程式員會對系統有初步的瞭解,對系統開發採用的技術、工具、開發技巧進行研究,同時同PM一同負責搭建軟體工程環境和軟體開發的環境。這樣的安排,出現的一個問題是編程人員與分析設計人員的溝通。它需要大家通暢、自由的交流,經可能對開發達成共識,減少資訊的丟失。 項目交流的方法,Brooks就OS360開發經驗,在“貫徹執行(Passing the Word)”一章中,進行了具體的講解。如,會議與大會、多重實現、電話日誌等。就小型項目而言,如果不考慮異地開發的情況,較正式的組內會議可以安排在一周一次,即周例會的形式。另外,在裡程碑之處安排評審會議,以對開發的進展、對需求的實現以及專案計劃進行調整和修正。而對於異地開發,或者使用者不在本地的情形,則建議採用電話會議等形式,效果雖然不如本地開發好,不過有聊勝於無。 “為什麼巴比倫塔會失敗?(Why Did the Tower of Babel Fail?)”又對軟體開發中的交流問題進行了強調,指出了文檔是溝通的一種重要方式。後續的 “提綱挈領(The Documentary Hypothesis)”則用類比的方式闡述了如何定義軟體項目的文檔集合,“另外一面(The other face)”討論了程式文檔的一些形式。這些觀點對實際工作也具有指導意義,相應的Rational Suite中Requisite Pro工具使用參考中,推薦了軟體項目的參考文檔集合。在C++和Domino若干項目的實踐中,發現最小的文檔集合包括需求文檔(Software Requirement Specification)、專案計劃(Software Development Plan)、架構設計、設計項目說明。其中,專案計劃不僅僅是進度,而是從軟體的組態管理、生命週期、資源分派、風險分析、培訓等方面進行描述,這部分的內容往往不局限於單個項目,而是在同一種類型的項目中具有共性。因此,可以在不同項目中共用。 總而言之,Brooks對文檔的建議是“專案經理聰明的做法都是:立刻正式產生若干文檔作為自己的資料基礎,哪怕這些迷你文檔非常簡單。接著,……”以及“如果一開始就認識到它們的普遍性和重要性,那麼就可以將文檔作為工具友好地利用起來,而不會讓它成為令人厭煩的繁重任務。通過遵循文檔開展工作,專案經理能更清晰和快速地設定自己的方向。” 面向變更的開發 “穩定點的生產思想特別不適合項目工作。我們傾向於忘記這一點:項目的全部目的就是讓自己死亡。項目生命中的唯一穩定點是死後僵硬……”(Peopeware); “軟體開發是減少混亂度(減少熵)的過程,所以它本身是處於亞穩態的。軟體維護是提高混亂度(增加熵)的過程,即使是最熟練的軟體維護工作,也只是放緩了系統退化到非穩態的進程。”——“未雨綢繆(Plan to Throw One Away)” 軟體開發本身就是一個具有無序趨勢的活動。當人們四處遊走,尋找一個類似於電腦硬體那樣流水線化的方式方法時,可能應該靜靜思考一下,這本身就是與開發內在發展規律相悖。並且,軟體開發是人類的思維創造活動,同詩歌、樂曲一樣,好像人類曆史上還沒有什麼為上述創造進行流水線化的嘗試。 從軟體開發產物的角度而言,CMM規範2級中的組態管理一般包括四個活動:組態識別、版本控制、變更控制和度量。組態識別和版本控制都是為了給變更提供一個穩定的承載基礎。而Brooks對360機器開發的進行了描述“在System/360工程模型中,在一大堆常規的黃顏色電線中,常常可以不經意地看到紫色的電線束。……這些更改過的接線使用紫色電線,看上去就像伸著一個受了傷的大拇指。”體現了組態管理的雛形,進一步提出了在軟體項目中“……軟體開發也需要用到“紫色線束”的手法。對於最後成為產品的程式碼,它更迫切地需要進行嚴密控制和深層次的關注。……而且需要文檔化。”——“整體部分(The Whole and the Parts)” 在CMM試驗項目以及後來的項目實踐中,為項目的文檔產出物進行標識是比較容易實現的。Internet上有大量的資料和模板可供參考。版本控制可以使用VSS或者Open Source的CVS,而CMM規範中反覆出現的“基準(baseline)”概念,在組態管理實踐的初期或者小規模的項目中,並不是強制性的。當組態識別和版本控制實踐到一定的程度之後,再推廣基準和變更控制,就相對容易得多。 即對於某種類型的項目,可以採用制定組態識別規範、識別文件類型、確定該類項目的目錄結構、建立版本控制機制來進行初期的實踐,具有一定的成熟度等級之後,再實施變更管理。變更使用“階段(量子)化、定期變更……量子(階段)化變更方法非常優美地容納了紫色線束技術:直到下一次系統構件的定期發布之前,都一直使用快速補丁;而在當前的發布中,把已經通過測試並進行了文檔化的修補措施整合到系統平台。”這種方法能在一定程度上緩解項目壓力、變更和品質之間的矛盾。 反覆式開發法 Brooks在“20年後的人月神話(The Mythical Man-Month after 20 Years)”明確提出了反覆式開發法的概念“漸進式開發模型更佳——漸進地精化”。這種開發方法對項目產生的激勵作用是不可估量的,作者在北卡羅來納大學時,“我常常會被螢幕上第一幅圖案、第一個可啟動並執行系統對團隊士氣產生的鼓舞效果而感到震驚。”而在C++的現實項目中,在極大的壓力下,當第一個可執行檔原型出現在開發人員面前時,長期的疲憊、沮喪一掃而空。從而,為繼續開發提供了動力。這裡,長時間高負荷工作並不是被提倡的,但漸進式開發是軟體開發動力學的一種重要手段。 反覆式開發法可以用“外科手術隊伍”、OO及設計模式的實現來實踐。物件導向架構的分析設計思想,並不一定非要用物件導向的語言實現。它的一個重要特點,是固化使用者要求或者是待開發系統中相對穩定的部分,以犧牲模型某個維度代價來得到較穩定的模型。然後,在該架構的基礎上不斷地迭代。“外科手術隊伍”則由具有豐富經驗的“外科醫生”操刀,來主持需求分析和建立迭代架構。少數的人能確保架構不帶有過多不必要的非結構性的功能特色,從而保證架構的簡捷和良好的擴充性。 反覆式開發法本身是對變更這個“怪物”的一劑良藥,不同迭代周期能較好地容納階段(量子)化的變更。在變更的同時,始終有可啟動並執行系統供調試、測試,從而確保項目的品質——品質決定成本,“遠遠超過終端使用者需求的品質是一種取得更高生產力的手段。”(《人件》,即將由清華大學出版社出版,譯者為UMLChina翻譯組方春旭、葉向群)。 同樣,Brooks在“未雨綢繆(Plan to Throw One Away)”中提出了拋棄型原型的概念,並在“《人月神話》的觀點:是或非?(Propositions of the Mythical Man-Month: True or False?)”中強調“因此,為捨棄而計劃,無論如何,你一定要這樣做。”反覆式開發法是容納原型,包括拋棄型和非拋棄型。而且,它是一個很好說服管理層和使用者的途徑——因為,不同的迭代周期和任務本來就在計劃之中。在C++的項目中,對於沒有堅持在架構設計完成之後,拋棄架構代碼原型,至今還有些遺憾,相應所付出的代價就是產品品質和開發人員對該項目信心的喪失。 另外一個提高項目產品品質的方法,Brooks在“整體部分(The Whole and the Parts)”的“系統整合調試”中給出了專家意見,“使用經過調試的構件單元”、“搭建充分的測試平台”、“一次添加一個構件”和“階段(量子)化、定期變更”。這在目前的實踐中依然有指導意義。現在的軟體測試水平相信業界人士都非常清楚:很少有正常化的測試;白盒測試基本不做;項目壓力過大,不斷壓縮測試時間……。因此,仔細的系統整合測試非常有必要,能夠做到《人月神話》中,OS360的系統測試一半已經非常不錯了。 專案計劃 專案計劃的重要性相信每個人都瞭然於胸。Brooks在“禍起蕭牆(Hatching a Catastrophe)”一文中提及了專案計劃/跟蹤。另外,在其他的許多章節中,闡述了計劃文檔化的重要性。這裡,專案計劃不僅僅指的是項目進度,採用Microsoft Project所畫出的僅僅是項目的進度。 在具體的實踐中,專案計劃可以從以下若干方面考慮:
- 項目描述:包括項目定義、名稱、背景、目標與範圍、交付物和驗收標準等;
- 項目組織圖:定義項目人員組成。註:這部分內容會根據項目的實施不斷調整;
- 軟體生命週期:依照項目特點決定合適的周期。並不是所有的項目都適用與迭代周期,也不是瀑布模型就一無是處,甚至有的項目需要瀑布模型作為主幹,在某個階段加入迭代特性。
- 專案管理:包括客戶管理、進度管理、成本管理、風險管理、培訓管理等;
- 組態管理:定義項目目錄結構、產物標識方法、版本控制等;
專案計劃必鬚根據使用者、項目特點仔細地考慮,它可能是寥寥數語,但是它的作用不在需求規格說明之下。專案計劃和需求規格說明是項目文檔集合中最基本的強制性文檔。 軟體開發中,理論與實踐是個亙古不變的話題。我們很有幸誕生在一個資訊共用的時代,能夠接觸到前人睿智的思想。“這個神奇的時代遠遠沒有結束,它依然在飛速發展。更多的樂趣,盡在將來。”——Brooks。 |