可以在线看黄的网站-可以免费在线看黄的网站-可以免费看污视频的网站-可以免费看毛片的网站-欧美电影免费看大全-欧美电影免费

談軟件巨著《人月神話》-大型軟件項目最佳實踐|系列二(人月神話 人件)

最近做了一個超大項目重構,其中對項目的管理也產生了非常多的問題,進行了深度項目的復盤之后,再回首去看軟件巨著《人月神話》體感更加豐富收獲非常多,故產生了此系列文章。

本系列文是軟件巨著《人月神話》讀書筆記,全系列分為三部分,會逐步介紹。

談軟件巨著《人月神話》-大型軟件項目最佳實踐|系列二(人月神話 人件)

本文講述的是作者在大型軟件項目中一些重要的實踐,主要有

談軟件巨著《人月神話》-大型軟件項目最佳實踐|系列二(人月神話 人件)

1. 團隊劃分,外科手術式隊伍

大型項目的經驗顯示:一擁而上的開發方法是高成本、速度緩慢、低效的。成本的主要組成部分是相互的溝通和交流,以及更正溝通不當所引起的不良結果(系統調試),需要協作溝通的人員的數量影響著開發成本。

不同人或者不同團隊之間效率差異會有很大,書中提到Sackman,Erikson和Grant曾對有經驗的程序員進行測量,發現最好的和最差的表現在生產率上有10:1的差異。

從 1963 年到 1966 年,作者項目設計、編碼和文檔工作花費了大約 5000 人年。如果人月可以等量置換的話,譬如 10 人隊伍。 作為一個尺度, 假設他們都非常厲害,比一般的編程人員在編程和文檔方面的生產率高 7 倍。 假定 OS/360 原有開發人員是一些平庸的編程人員(這與實際的情況相差很遠)。 同樣,假設另一個生產率的改進因子提高了 7 倍, 因為較小的隊伍所需較少的溝通和交流。 那么, 5000/(10× 7× 7) = 10,他們需要 10 年來完成 5000 人年的工作。一個產品在最初設計的 10 年后才出現,還有人會對它感興趣嗎?或者它是否會隨著軟件開發技術的快速進步,而顯得過時呢?

總之,團隊的規模太大,帶來的溝通成本也隨之升高,總體效率隨之降低;團隊規模太小,可能單位效率提升了,但是總體進度太慢了,無法及時完成真正有用的產品。

如何解決上面兩難的問題呢,Harlan Mills 的提議提供了一個嶄新的、創造性的解決方案 。 Mills 建議大型項目的每一個部分由一個團隊解決,但是該隊伍以類似外科手術的方式組建,而并非一擁而上,我們叫做“外科手術隊伍”

外科手術隊伍核心設計:同每個成員截取問題某個部分的做法相反, 由一個人來進行問題的分解, 其他人給予他所需要的支持,以提高效率和生產力。

團隊陣容以一個主程序員為核心,配合9名其他專業人員形成一個團隊,如下圖所示:

談軟件巨著《人月神話》-大型軟件項目最佳實踐|系列二(人月神話 人件)

  • 首席程序員:決策一切并實際動手編程,親自定義功能和性能技術說明書,設計程序,編制源代碼,測試以及書寫技術文檔,首席程序員需要極高的天分、 十年的經驗和應用數學、業務數據處理或其他方面的大量系統和應用知識
  • 副手:作為后備,能完成任何一部分工作,但是相對具有較少的經驗。他的主要作用是作為設計的思考者、 討論者和評估人員。他需要詳細了解所有的代碼, 研究設計策略的備選方案。 顯然, 他充當外科醫生的保險機制。 他甚至可能編制代碼,但針對代碼的任何部分,不承擔具體的開發職責。
  • 管理員:外科醫生是老板,他必須在人員、加薪等方面具有決定權,但他決不能在這些事務上浪費任何時間。 因而, 他需要一個控制財務、 人員、 工作地點安排和機器的專業管理人員, 該管理員充當與組織中其他管理機構的接口。
  • 編輯:外科醫生負責產生文檔——出于最大清晰度的考慮,他必須書寫文檔。對內部描述和外部描述都是如此。 而編輯根據外科醫生的草稿或者口述的手稿, 進行分析和重新組織,提供各種參考信息和書目,對多個版本進行維護以及監督文檔生成的機制。
  • 兩個文秘:管理員和編輯每個人需要一個秘書,配合管理員和編輯共同工作。
  • 程序職員:他負責維護編程產品庫中所有團隊的技術記錄。該職員接受秘書性質的培訓,承擔機器碼文件和可讀文件的相關管理責任
  • 工具維護人員:保證所有基本服務的可靠性, 以及承擔團隊成員所需要的特殊工具(特別是交互式計算機服務) 的構建、 維護和升級責任。
  • 測試人員:負責編寫測試用例,搭建測試環境并測試。
  • 語言專家:尋找一種簡潔、 有效的使用語言的方法來解決復雜、 晦澀或者棘手的問題。

傳統的團隊:將工作進行劃分,每人負責一部分工作的設計和實現;

外科手術團隊:實際設計完全由外科醫生完成,其他人負責填充實現細節與提供必要的幫助。

外科手術式隊伍的好處在于:

  • 減少溝通的成本,在傳統的隊伍中,大家是平等的,出現觀點差異的時候,不可避免的需要討論和妥協,在外科式隊伍中,不存在利益的差別,也不存在因為意見不合帶來的策略和系統接口上的不一致,觀點不一致由外科醫生單方面來統一。
  • 保證概念完整性,系統的設計和程序代碼都由外科醫生主要負責,保障了從設計到實現上的概念完整性。

如果整個工作能控制在范圍之內, 10 人的團隊無論如何組織, 總是比較高效的。但是, 當我們需要面對幾百人參與的大型任務時, 如何應用外科手術團隊的概念呢?

首先整個系統必須具備概念上的完整性, 要有一個系統結構師從上至下地進行所有的設計。 要使工作易于管理, 必須清晰地劃分體系結構設計和實現之間的界線, 系統結構師必須一絲不茍地專注于體系結構。

然后需要使用分解的技術,分解到一個個獨立部分,每個部分由一個外科手術團隊保障概念完整性。項目整體的溝通只需要再外科醫生之間進行溝通和討論,大大降低成本。

2. 保持概念完整性,貴族專制

絕大多數歐洲的大教堂中,由不同時代、不同建筑師所建造的各個部分之間,在設計或結構風格上都存在著許多差異。 后來的建筑師總是試圖在原有建筑師的基礎上有所“ 提高”,以反映他們在設計風格和個人品味上的改變。所以, 在雄偉的哥特式的教堂上,依附著祥和的諾曼第風格十字架,它在顯示上帝榮耀的同時,展示了同樣屬于建筑師的驕傲。

與之對應的是, 法國城市蘭斯(Reims) 在建筑風格上的一致性和上面所說的哥特式大教堂形成了鮮明的對比。 設計的一致性和那些獨到之處一樣, 同樣讓人們贊嘆和喜悅。 如同旅游指南所述, 風格的一致和完整性來自 8 代擁有自我約束和犧牲精神的建筑師們, 他們每一個人犧牲了自己的一些創意, 以獲得純粹的設計。 同樣, 這不僅顯示了上帝的榮耀, 同時也體現了他拯救那些沉醉在自我驕傲中的人們的力量。

對于計算機系統而言,盡管它們通常沒有花費幾個世紀的時間來構建,但絕大多數系統體現出的概念差異和不一致性遠遠超過歐洲的大教堂。 這通常并不是因為它由不同的設計師們開發,而是由于設計被分成了由若干人完成的若干任務。

作者主張在系統設計中,概念完整性應該是最重要的考慮因素。也就是說為了反映一系列連貫的設計思路,寧可省略一些不規則的特性和改進,也不提倡獨立和無法整合的系統,哪怕它們其實包含著許多很好的設計。

短小精干的隊伍帶來了新的問題,如何對大項目進行合理的分割?

這依賴于一個很重要的前提:概念完整性。系統設計中,概念完整性是最重要的考慮因素。概念的完整性的確要求系統只反映唯一的設計理念,用戶所見的技術說明來自少數人的思想。

如何獲得系統的完整性? 答案是貴族專制,設計必須由一個人或非常少數互有默契的人員來實現并理清邊界,然后據此分割執行。對于非常大型的項目, 將設計方法、 體系結構方面的工作與具體實現相分離是獲得概念完整性的強有力方法。” [同樣適用于小型項目 ]

3. 避免畫蛇添足,要自律

在開發第一個系統時,結構師傾向于精煉和簡潔。他知道自己對正在進行的任務不夠了解,所以他會謹慎仔細地工作。同時他對會不斷產生的裝飾和潤色功能,把這些功能都擱置在一邊,作為下一個項目的內容。第一個項目遲早會結束,而此時的結構師,對這類系統充滿了十足的信心,熟練掌握了相應的知識,并且時刻準備開發第二個系統。

第二個系統是設計師們所設計的最危險的系統,一種普通傾向是過分地設計第二個系統,向系統添加更多修飾功能和想法,它們曾在第一個系統中被小心謹慎地推遲了。如果如同ovid所述,是一個”大餡餅“。例如,后來被嵌入到7090的IBM709系統,709是非常成功和簡潔的704系統進行升級的二次開發項目,709的操作集合被設計的如此豐富和充沛,以至于只有一般操作被常規使用。

所以書中提到系統設計師們,在系統設計時,需要對項目有節制,有些東西可以不添加,不要過度設計,不要過度自信,保持警覺,確保初始的概念和目標的充分體現,而不是讓一些次要功能喧賓奪主。

4. 概念完整性貫徹,一些方法

概念的完整性不僅僅要在專制的貴族和系統設計師這一層面上充分理解并傳達,在系統的實現人員中,也要充分傳達。在不理解業務背景的情況下,開發者也很難寫出優秀的代碼。

作者在這一章介紹了很多方法達到之一目的,包括規格說明手冊,形式化定義(如原型圖)、會議和大會、多重實現、電話日志、產品測試。當然這些方法在如今可能已經過時了或有更好的方式,但是通過種種方式保證軟件開發的進度不偏離最初的概念和目標,是實現項目成功的重要保障。實際上在當代的軟件開發中,也有一些措施來實現這一目標,比如各種項目管理工具,版本化文檔工具等。

5. 溝通,巴比倫塔失敗的教訓

據《創世紀》記載,巴比倫塔是人類繼諾亞方舟之后的第二大工程壯舉,但巴比倫塔同時也是第一個徹底失敗的工程。

文中以巴比倫塔建設失敗的神話故事引出了”溝通“的重要性。當上帝消除了統一的語言,人們失去了交流的手段,即使其他條件都能滿足,巴比倫塔也以失敗告終。

文中他們分析了必要的有利條件都已經具備,但還缺乏兩個方面——交流, 以及交流的結果——組織。他們無法相互交談, 從而無法合作。 當合作無法進行時, 工作陷入了停頓。 通過史書的字里行間, 我們推測交流的缺乏導致了爭辯、 沮喪和群體猜忌。很快,部落開始分裂——大家選擇了孤立,而不是互相爭吵。

溝通時確保團隊思想統一、目標一致的最重要手段。那么,如何進行有效的溝通呢:

  • 時常保持非正式的交流溝通。比如面對面口頭的交流或者電話等過遠程交流,不論哪種形式,交流的內容都應形成文字記錄。
  • 常規性項目會議。關鍵成員定期組織項目例會,討論主題順明確,結論有效,會議內容形成文字記錄。
  • 項目必須擁有共享的工作手冊。這是一套文檔的集合,在在項目初期就確定各個文檔的結構,然后在項目過程中不斷的填寫細化完善,每個版本應該擁有明確的時間記錄和變更說明。
  • 文檔其實是高效溝通的一種有效方式。準備文檔時,需要要仔細的核對實際情況,謹慎的措辭;寫文檔時,各種問題和討論都會浮出水面,必須進行決定;寫完文檔后,所有的想法和決定都都以文字的方式確定并記錄,對每個人的思想進行統一。文檔能夠使各項計劃和決定在整個團隊范圍內得到交流。

項目經理的主要日常工作就是溝通,而不是做出決定。他的職責是使每個人都向著相同的方向前進。

即使再三強調溝通的重要性,但是由于主觀或者客觀的原因,在實際項目過程中還是會發現溝通不足導致的問題。書中也提出了幾種方式如何減少溝通也能達到有效協作的目標:

  • 每個人不是必須關注所有的內容,各個部分應該只暴露對外表現,而內部實現應該封裝不對外暴露。這段內容體現到代碼上就是:面向接口編程,不要依賴實現邏輯。
  • 小而精的團隊搭配,保持一個首席程序員完成所有的設計和代碼偏寫工作,其他人進行輔助配合,確保概念的完整性和一致性,減少溝通。
  • 團隊協作就要形成組織結構,團隊組織的目的是為了減少必要的交流和協作量,人力劃分和職責范圍必須明確并且清晰。團隊中禁止雙重領導,團隊是樹狀結構,交流是網狀結構,需要補充特殊組織機制來克服樹狀組織結構中缺乏交流的困難。

團隊組織的目標是為了減少必要的交流和協作量,為了減少交流,組織結構包括了人力劃分(division of labor) 和限定職責范圍(specialization of function)。

傳統的樹狀組織結構反映了權力的結構原理——不允許雙重領導,組織中的交流是網狀, 而不是樹狀結構, 因而所有的特殊組織機制(往往體現成組織結構圖中的虛線部分)都是為了進行調整,以克服樹狀組織結構中交流缺乏的困難。

6. 胸有成竹,工作量的預估

系統編程需要花費多長的時間?需要多少工作量?如何進行估計?

先前他推薦了合理的軟件進度安排應該遵循:計劃進度(1/3)、編碼(1/4)、構建測試(1/4)和系統測試(1/4)。僅僅通過對編碼部分的估計,然后應用上述比率對整個任務進行估計是錯誤的。編碼大約之戰問題的1/6左右,編碼估計或者比率的錯誤可能導致不合理荒謬結果。

第二,必須聲明的是,構建獨立小型程序的數據不適用于編程系統產品。就好像把 100 碼短跑記錄外推, 得出人類可以在 3分鐘之內跑完 1 英里的結論一樣。

作者當時編程量化方法將程序員的生產效率細化到指令/年(他們當年寫的是匯編,高級語言那個時候還很少)。這個實際意義不大,但仍然是一個有趣的參考,最終的結論是: 工作量=常數*指令數量^1.5,也就是說工作時長跟代碼數量是指數關系而不是線性關系,隨著代碼數量的增長,工作時長是指數級上升的。

然后舉例說一些關于編程人員生產率的研究,提出的一些估計技術。生產率會根據任務本身復雜度和困難程度表現出顯著差異。無法用代碼量來預估排期,使用適當的高級語言,編程的生成效率可以提高5倍。

7. 減少程序空間,削足適履

這一章主要是講程序大小的,包括代碼大小和內存占用的大小。代碼大小現在應該已經不是軟件開發的重要考量了吧? 但是這一問題在如今的App開發中應該也有,雖然很多公司毫不在乎占用用戶幾百M的存儲空間……當然在前端還存在另外一個問題,即過大的代碼包會耗費過多的流量,尤其是在早年的移動端開發中,那時候流量很金貴,現在這樣的顧慮逐漸變少了,但是一直都存在的顧慮是代碼的加載速度,當然這一問題也可以通過分包懶加載來解決了。總而言之,當年的那些經驗在前端領域適用的已經不多了,但是在客戶端領域可能仍然適用。

內存當然始終是一個問題,但是應該主要考慮不要發生內存泄露的問題,自動的垃圾收集可以解決大部分問題。計算機硬件的進步真的極大地降低了軟件工程的難度。

8. 項目文檔的重要性,提綱挈領

這一章主要是介紹文檔的重要性,對于項目經理來說,文檔是很重要的,它包含了項目目標、產品的技術說明、時間、資金預算、工作空間的分配和人員的組織結構。

  • 文檔的重要性主要體現在: 明確的書面記錄會讓分歧更明朗,使混沌的狀態變得清晰、明確。
  • 文檔降低了溝通的負擔。
  • 文檔便于項目經理跟蹤項目的進度狀態。

9. 唯一不變的是變化,未雨綢繆

軟件領域的名言:“唯一不變的就是變化本身”,潛臺詞就是“其他都會發生變化”

變化意味著不可預料,不可提前準備,準備好的可能徒勞、不可控,變化的情況有很多,例如:

  • 用戶不會在初期提供明確的需求,用戶的實際需要和用戶的感覺會隨著程序的構建、測試和使用而變化。
  • 軟件開發和運行過程中的環境不一定一致,甚至運行環境本身也在變化。
  • 設計人員在軟件開發完成之后才能意識到設計上的缺陷,從而視圖在下一個版本中彌補
  • 團隊成員由于各種因素(私人的或者公司的)變化,甚至核心成員發生變化可能直接導致軟件推翻重來。

系統必然會面臨各種變化,你開發的軟件必然會在修修補補中變得面目全非,最初的設計必須在各種妥協中打上各種丑陋的補丁。無論是多么良好設計的系統,都會走向混亂,區別只是這個過程的快慢而已。因此,好的設計會讓這個過程盡可能的慢,盡可能地不那么痛苦,我們能做的就是眼光盡量放長遠,讓我們的代碼盡可能地具有高可擴展性并且易于維護。而且,在面對不得不進行重構時,做好心里準備。

一些Bug有趣的數據,對于一個廣泛使用的程序,其維護總成本通常是開發成本的 40%或更多。令人吃驚的是,該成本受用戶數目的嚴重影響。用戶越多,所發現的錯誤也越多。

談軟件巨著《人月神話》-大型軟件項目最佳實踐|系列二(人月神話 人件)

起初,上一個版本中被發現和修復的 bug,在新的版本中仍會出現。 新版本中的新功能會產生新的 bug。 解決了這些問題之后, 程序會正常運行幾個月。接著, 錯誤率會重新攀升。 Campbell 認為這是因為用戶的使用到達了新的熟練水平,他們開始運用新的功能。這種高強度的考驗查出了新功能中很多不易察覺的問題。

程序維護中的一個基本問題是——缺陷修復總會以(20- 50) %的機率引入新的 bug,所以整個過程是前進兩步,后退一步。

系統軟件開發是減少混亂度(減少熵)的過程,所以它本身是處于亞穩態的。軟件維護是提高混亂度(增加熵) 的過程, 即使是最熟練的軟件維護工作, 也只是放緩了系統退化到非穩態的進程。

10. 提升開發效率的工具,干將莫邪

巧匠因為他的工作而出名(工匠精神)。

好的開發團隊自然要有自己一套比較完好的開發工具和開發環境,用來提供生產力和生產效率。

本章主要向我們傳達的意思是: 工具對于軟件產業的重要性,工具需要做到統一,需要有專人進行維護。

11. 如何讓整體正常運行,整體部分

當每個功能模塊開發、測試完成,開始多個模塊之間進行集成測試;或者一個子系統開發測試完成,開始多個子系統進行集成測試。單個模塊獨立運行對最終用戶根本沒有意義,所有模塊配合到一起形成完整的業務鏈路才能作為交付物。

這時的人們都樂觀地認為"總算都開發完了,集成調試一下就都搞定了"。其實,這才是痛苦的開始。各種之前不相關的人和資源需要協調,這些人互相屬于不同的團隊,團隊之間職責劃分不清晰,這些都開始極度考驗每個團隊負責人的水平–"開始推卸責任":因為模塊與模塊之間的適配部分沒有人負責開發實現,每個團隊都理所當然的認為這些公共部分是對方負責的。

即使各個模塊獨立運行正確,也不一定能夠集成。事實上,預先定義的集成標準并不是完美的、嚴格的。這就導致不同團隊對標準的理解有差異,實現出來的模塊總會有差異,這些差異只有在集成的過程中才能發現。每個模塊都認為自己的符合標準的,對方需要修改才能按照標準進行集成。

這些技術問題相對還是容易解決的,更麻煩的是各個系統是不同的團隊或者組織開發的,系統間進行集成就必須同時協調多方組織的人員。在權力不能到達的情況下,協調多方利益并不完全一致的組織簡直是時間殺手。

書中也指出:"系統調試(相對于單元測試)所花費的時間會比預料的更長"。針對這個問題,我在書中沒有找到針對性的解決方案,最好是早集成、早暴露、早解決。

同時我們可以在設計系統結構時精心設計,減少各個部分間的耦合,各個模塊的獨立性越高,系統級的bug的可能性就越低。重構過的模塊在合進整體的時候仍然需要對系統整體進行測試,而不是僅僅測試重構過的模塊。如自上而下的設計、構件單元調試等。

12. 進度管理和監控的方法–防止禍起蕭墻

在我們的工作經驗中,很多大型軟件項目都會比預期延后,在事后的總結中卻又并不能發現重大的失誤,那么,到底是什么導致了項目的整體落后呢?

書中提到:"一天一天的進度落后比重大災難更難以識別,不易防范,更加難以彌補"。確實是這樣的,某天關鍵成員請假了,某天需要的環境沒有到位,某天公司的網絡突然換掉了,這些隱藏在日常過程中的小事,一天一天的把進度延后了。而且沒有人能夠及時發覺,在發覺進度延后之后,也會下意識的認為:明天就好了,加加班就趕回來了。慢性的進度偏離絕對是士氣殺手。沒有人總結,沒有人匯報,也就沒有人解決,時間就這樣一天天的過去了,直到項目到期時才發覺:"時間都去哪了"?

隱藏偏離是人的本性,每個人都不希望將自己的缺點暴露在人前,軟件開發人員更傾向自己悶頭鉆研而不善于求助他人,更希望自己將問題搞定而沒有發覺進度已經延后。作為項目管理里者不能奢望團隊成員都能如實的、及時的匯報工作進展。項目管理者需要通過各種方式維護一種信任、平等、合作、互助的工作氛圍,逐漸的引導或者影響開發人員將實際情況表達出來。

項目經理必須使用嚴格的進度表來控制項目,進度表由里程碑和日期組成。每個里程碑必須是具體的、特定的、可度量的事件,能夠進行清晰定義。項目經理積極的跟進每項工作進展才可能盡量準確的了解項目的真實進展,從而進行資源的調配。

項目進度滯后往往如溫水煮青蛙一樣讓我們難以應付,最重要的就是要防微杜漸。

13. 提供面向用戶的文檔,另外一面

程序向用戶所呈現的面貌(界面、文檔、注釋)與提供給機器識別的內容(代碼)同樣重要。不管是獨立程序還是系統軟件,都應該編寫注釋,因為人會遺忘的。

注釋需要描述事情如何,還應描述為什么,注釋信息應該以段落的方式向程序中插入必要的記述生文字,同時可以借助源代碼的固定格式來附件更多的文檔信息關提升可讀性。

除了面向開發者的項目文檔和說明之外,軟件開發也需要編寫詳勿的面向用戶的文檔,文檔需要包含軟件的目的、運行環境、轉輸入輸出范圍、實現的功能和使用的算法、輸入輸出的格式、排操作指令、選項、運行時間、輸出結果的精度和校驗方式等等。

除此之外,還需要充分的測試用例來說明程序的功能和邊界。

相關新聞

聯系我們
聯系我們
在線咨詢
分享本頁
返回頂部